platform-ui-home/workbench_design/Inside the workbench.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (view) (download) (as text)

1 : sxenos 1.1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 :     <html>
3 :     <head>
4 :     <meta content="text/html; charset=ISO-8859-1"
5 :     http-equiv="content-type">
6 :     <title>Inside the Workbench: A guide to the workbench internals</title>
7 :     </head>
8 :     <body>
9 :     <div style="text-align: center;">
10 :     <div style="text-align: left;">
11 :     <table border="0" cellpadding="2" cellspacing="5" width="100%">
12 :     <tbody>
13 :     <tr>
14 :     <td colspan="2" align="left" bgcolor="#0080c0" valign="top"><b><font
15 :     color="#ffffff" face="Arial,Helvetica"> Platform UI Design Document<br>
16 :     </font></b></td>
17 :     </tr>
18 :     </tbody>
19 :     </table>
20 :     </div>
21 :     <span style="font-weight: bold;"><font size="+2"><span
22 :     style="font-weight: bold;"><font size="+3"><br>
23 :     Inside the
24 :     Workbench<br>
25 :     A guide to the workbench internals<br>
26 :     <br>
27 :     </font></span></font></span></div>
28 :     <br>
29 :     <div style="margin-left: 40px;"><span style="font-weight: bold;">Summary<br>
30 :     </span>This document describes how the Eclipse 3.1 workbench works. It
31 :     describes the infrastructure that makes views and editors work. The
32 :     goal is to make the reader familiar with important classes in the
33 :     workbench, and how they interact. It is assumed that the reader is
34 :     already familiar with the workbench APIs, and with creating views,
35 :     editors, action sets.<br>
36 :     <br>
37 :     <span style="font-weight: bold;">Stefan Xenos, IBM</span><br>
38 : sxenos 1.2 July 12, 2005<br>
39 : sxenos 1.1 <br>
40 :     </div>
41 :     <br>
42 :     <hr style="width: 100%; height: 2px;">
43 :     <h1><a class="mozTocH1" name="mozTocId932753"></a>Table of Contents</h1>
44 :     <ul id="mozToc">
45 :     <!--mozToc h1 1 h2 2 h3 3 h4 4 h5 5 h6 6--><li><a href="#mozTocId932753">Table
46 :     of Contents</a></li>
47 :     <li><a href="#mozTocId777378">1.0 Introduction </a></li>
48 :     <li><a href="#mozTocId611837">2.0 Inside a part </a>
49 :     <ul>
50 :     <li><a href="#mozTocId683987">2.1 Part Lifecycle </a></li>
51 :     <li><a href="#mozTocId623821">2.2 Part Construction</a></li>
52 :     </ul>
53 :     </li>
54 :     <li><a href="#mozTocId304467">3.0 Workbench Layout </a>
55 :     <ul>
56 :     <li><a href="#mozTocId913623">3.1 An example layout</a></li>
57 :     <li><a href="#mozTocId994793">3.2 Zoom / Unzoom protocol </a></li>
58 :     <li><a href="#mozTocId364295">3.3 Layout protocol </a></li>
59 :     <li><a href="#mozTocId867109">3.4 PartStack: Communicating with
60 :     the Presentation API </a></li>
61 :     <li><a href="#mozTocId854140">3.5 PartSashContainer: The main
62 :     workbench layout </a></li>
63 :     <li><a href="#mozTocId370659">3.6 Drag / Drop</a></li>
64 :     </ul>
65 :     </li>
66 :     <li><a href="#mozTocId438049">3.0 Action Bars</a>
67 :     <ul>
68 :     <li><a href="#mozTocId808539">3.1 Editor Action Bars </a></li>
69 :     <li><a href="#mozTocId809219">3.2 Action Sets </a></li>
70 :     <li><a href="#mozTocId846891">3.3 View Actions</a></li>
71 :     </ul>
72 :     </li>
73 :     <li><a href="#mozTocId453994">4.0 General Conventions</a>
74 :     <ul>
75 :     <li><a href="#mozTocId451497">4.1 Objects must not be returned
76 :     through API until they are fully initialized</a></li>
77 :     <li><a href="#mozTocId959546">4.2 No method may open a modal
78 :     dialog unless its JavaDoc says so</a></li>
79 :     <li><a href="#mozTocId877708">4.3 Lazy creation should happen as
80 :     late as possible</a></li>
81 :     <li><a href="#mozTocId758931">4.4 getters should not modify the
82 :     thing they are supposed to measure</a></li>
83 :     </ul>
84 :     </li>
85 :     </ul>
86 :     <div style="margin-left: 40px;"><span style="font-weight: bold;"></span></div>
87 :     <h1><a class="mozTocH1" name="mozTocId777378"></a><span
88 :     style="font-weight: bold;"></span><span style="font-weight: bold;">1.0
89 :     Introduction</span>
90 :     <br>
91 :     </h1>
92 :     <span style="font-weight: bold;"></span>
93 :     <br>
94 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
95 :     1.0.1: Ownership of views and editors<br>
96 :     <br>
97 :     </span></div>
98 :     <div style="text-align: center;"><img alt=""
99 :     src="workbench_high_level.PNG" style="width: 600px; height: 340px;"><br>
100 :     </div>
101 :     <br>
102 :     Figure 1.0.1 shows how views and editors are owned by the workbench.<br>
103 :     <br>
104 :     The Workbench contains one or more WorkbenchWindows, each of which
105 :     contain zero or more WorkbenchPages. The WorkbenchWindow supplies the
106 :     trim widgets, and the WorkbenchPage supplies the window
107 :     contents. In theory, a WorkbenchWindow can contain any number of pages,
108 :     but in practice there is never more than 1 page in a window.<br>
109 :     <br>
110 :     Views and editors are owned by the page, through a ViewFactory and
111 :     EditorManager respectively. EditorManager stores the list of editors
112 :     and their shared
113 :     resources, and ViewFactory stores a reference counted list of views.
114 :     The workbench works in terms of EditorReferences and ViewReferences,
115 :     and in this article the terms "editor" or "view" will refer to these
116 :     classes specifically. In situations where the distinction between
117 :     editors and views is not important, we will simply use the term "part".
118 :     The implementation of the part (typically an IEditorPart or IViewPart)
119 :     is created lazily when it is first needed. As shown in figure 1.0.2, a
120 :     part reference exists for every tab but the implementation is only
121 :     created the first time it becomes visible.<br>
122 :     <br>
123 :     The page owns a set of perspectives. Perspectives contain a layout and
124 :     information about what action sets to enable. Although perspectives
125 :     appear to contain views and the editor area, they only own a layout.
126 :     The page itself maintains a reference count for how many perspectives
127 :     are using each view, and has complete ownership of the parts and editor
128 :     area.<br>
129 :     <br>
130 :     Not shown in figure 1 are the classes PerspectiveHelper and
131 :     EditorAreaHelper. These classes exist largely for historic purposes,
132 :     and in this article we will treat the former as though it were part of
133 :     the Perspective class and the latter as part of the WorkbenchPage class.<br>
134 :     <br>
135 :     <br>
136 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
137 :     1.0.2: Workbench objects and what they look like<br>
138 :     <br>
139 :     </span></div>
140 :     <div style="text-align: center;"><img alt="" src="what_you_see.PNG"
141 :     style="width: 892px; height: 700px;"><br>
142 :     </div>
143 :     <br>
144 :     <h1><a class="mozTocH2" name="mozTocId611837"></a>2.0 Inside a part<br>
145 :     </h1>
146 :     <div style="text-align: center;"><span style="font-weight: bold;">
147 :     Figure 2.0.1: Anatomy of a part</span><br>
148 :     </div>
149 :     <div style="text-align: center;"><img alt="" src="anatomy_of_a_part.PNG"
150 :     style="width: 420px; height: 280px;"><br>
151 :     </div>
152 :     Internally, a part consists of several objects (figure 2.0.1).
153 :     WorkbenchPartReference is the topmost representation of the part.
154 :     Depending on where it is used, the part reference is often exposed as
155 :     IWorkbenchPartReference, IViewReference, IEditorRefenece, or
156 :     IPresentablePart, or PartPane. These are essentially different
157 :     interfaces to the same object. The I*Reference interfaces are
158 :     implemented directly by WorkbenchPartReference and its subclasses.
159 :     IPresentablePart is a simple adapter that redirects its methods
160 :     directly to the part. PartPane implements the LayoutPart protocol which
161 :     is needed to insert the part into the workbench layout. PartPane also
162 :     manages the SWT resources (such as a top-level control) that are needed
163 :     to include the control in the workbench layout.<br>
164 :     <br>
165 :     The part implementation (the IEditorPart or IViewPart) is owned by the
166 :     reference. When the
167 :     implementation is created, it is given a PartSite. The PartSite (seen
168 :     by client code as an IWorkbenchPartSite, IEditorSite, or IViewSite)
169 :     allows the client code to communicate with the reference and manages
170 :     services created for the implementation.<br>
171 :     <br>
172 :     WorkbenchPartReferences allocate SWT resources lazily as needed.
173 :     Once created, the part reference must be explicitly disposed. Disposing
174 :     the reference cleans up all of its resources (including the part
175 :     implementation itself) and guarantees that the reference will never
176 :     allocate additional resources. The workbench page disposes the part
177 :     reference once it is certain that it will never need to use that part
178 :     again. Unlike SWT controls, it is valid to continue using the reference
179 :     after it has been disposed. A disposed part reference is unlikely to do
180 :     anything interesting besides returning its name and cannot be used with
181 :     any
182 :     methods in the workbench page. Since it is hard (or impossible) for
183 :     clients to track the lifecycle of the reference, they are permitted to
184 :     continue using its public interface after disposal.<br>
185 :     <br>
186 :     <h2><a class="mozTocH3" name="mozTocId683987"></a>2.1 Part Lifecycle<br>
187 :     </h2>
188 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
189 :     2.1.1: WorkbenchPartReference states<br>
190 :     <br>
191 :     </span></div>
192 :     <div style="text-align: center;"><img alt="" src="part_states.PNG"
193 :     style="width: 445px; height: 590px;"><br>
194 :     </div>
195 :     Figure 2.1.1 shows the part lifecycle as a state machine. The part
196 :     reference stores its current state in the integer state field.<br>
197 :     <br>
198 :     Notes:<br>
199 :     <ul>
200 :     <li>The part is in a distinct state while it is in the process of
201 :     creating the implementation. It cannot be recursively re-created or
202 :     disposed while it is in this state.</li>
203 :     <li>The part implementation cannot be recreated once the reference
204 :     has been disposed.</li>
205 :     <li>Parts cannot return to the lazy state once they have been
206 :     created. This is a limitation in the 3.1 implementation, not a
207 :     functional requirement.</li>
208 :     <li>It is valid to continue using the public interface of
209 :     WorkbenchPartReference once it has been disposed, however a disposed
210 :     reference cannot be passed to methods in workbench page (since it is,
211 :     by definition, no longer part of any page).</li>
212 :     </ul>
213 :     <h2><a class="mozTocH3" name="mozTocId623821"></a>2.2 Part Construction</h2>
214 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
215 :     2.2.1: Message sequence for creating a part<br>
216 :     <br>
217 :     </span></div>
218 :     <div style="text-align: center;"><img alt="" src="part_creation_msc.PNG"
219 :     style="width: 892px; height: 700px;"><br>
220 :     </div>
221 :     <br>
222 :     Figure 2.2.1 shows the process for creating a part. The horizontal
223 :     line separates the two phases of creating a part. First the part is
224 :     added to the layout, and then a real implementation is attached. These
225 :     are two distinct operations, and the part can exist as a tab in the
226 :     page with no implementation for some time before it becomes visible.
227 :     This diagram focuses on the interactions with the part reference, and
228 :     skips the details of adding the part to the presentation and creating
229 :     the part site.<br>
230 :     <br>
231 :     Author's note: there are situations where it would be useful to only
232 :     add the part to the layout if it can be created successfully (this
233 :     would be necessary to pass a PartInitException thrown in the
234 :     implementation's init method up through IWorkbenchPage.openEditor). In
235 :     these situations, it would be possible to merge both operations into
236 :     one atomic operation by creating the part before adding it to the
237 :     layout. It is unknown if this would create event ordering bugs in
238 :     client code.<br>
239 :     <br>
240 :     <span style="font-weight: bold;"></span>
241 :     <h1><a class="mozTocH2" name="mozTocId304467"></a>3.0 Workbench Layout<br>
242 :     </h1>
243 :     <br>
244 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
245 :     3.0.1: LayoutPart hierarchy</span><br>
246 :     <img alt="" src="LayoutPart_hierarchy.PNG"
247 :     style="width: 302px; height: 412px;"><br>
248 :     </div>
249 :     <br>
250 :     The workbench layout provides supports arranging parts using drag &amp;
251 :     drop, resizing and detaching parts, fast views, etc. This section gives
252 :     a quick overview of the layout mechanism.<br>
253 :     <br>
254 :     Anything in the workbench layout is a LayoutPart. A LayoutPart manages
255 :     a set of widgets in a rectangular region of the screen, can contain or
256 :     arrange other layout parts, returns size constraints, responds to drag
257 :     events, etc. To this extent, a LayoutPart is very similar to a custom
258 :     SWT Control. However, LayoutPart differs from Control in several
259 :     important ways.<br>
260 :     <ul>
261 :     <li>The LayoutPart hierarchy is not the same as the widget hierarchy.
262 :     Even though one LayoutPart may contain another, their widgets may be
263 :     peers. This allows drag and drop to work on platforms where SWT doesn't
264 :     support reparenting, since a LayoutPart can be reparented without
265 :     reparenting its widgets.<br>
266 :     </li>
267 :     <li>LayoutParts mainly perform layout-related tasks, unlike Controls
268 :     which also supply behavior and appearance. The behavior of a LayoutPart
269 :     is supplied by the widgets it arranges.<br>
270 :     </li>
271 :     <li>LayoutParts know about higher-level concepts like zoom, and can
272 :     specify constraints about their own size.<br>
273 :     </li>
274 :     </ul>
275 :     Figure 3.0.1 shows the LayoutPart hierarchy. Notice the symmetry
276 :     between the View* classes and the Editor* classes. These classes exist
277 :     largely for historical reasons, and it should be possible to move all
278 :     of the functionality into the Part* base classes or other objects in
279 :     the system. Since all of the interesting behavior comes from the Part*
280 :     classes, the remainder of this section will focus on them without
281 :     describing the minor differences between views and editors.<br>
282 :     <br>
283 :     PartSashContainer arranges a set of child parts separated by a bunch of
284 :     sashes. This is the object that implements the most visible aspects of
285 :     the workbench layout. It arranges rectangular regions separated by
286 :     sashes, and allows new regions to be created by splitting old ones. It
287 :     also supports the size constraints that make minimized views possible,
288 :     and determines what it means for one of these regions to be maximized.
289 :     Typically, a PartSashContainer contains a bunch of PartStacks, although
290 :     it is also possible for it to contain another PartSashContainer. The
291 :     latter case occurs since the editor area and the perspective both use a
292 :     PartSashContainer for their layout and one is embedded inside the
293 :     other. PartSashContainer owns its stacks but does not own an embedded
294 :     PartSashContainer. In a workbench window, there is one
295 :     PartSashContainer for each perspective and one for the editor area
296 :     itself.<br>
297 :     <br>
298 :     PartStack arranges a stack of PartPanes. PartStack allows the
299 :     presentation API to participate in the workbench layout. The code for
300 :     creating the tabs and arranging parts is supplied by the active
301 :     presentation.<br>
302 :     <br>
303 :     PartPane allows views and editors to participate in the workbench
304 :     layout. Although PartPanes are arranged by PartStacks they belong to
305 :     part reference, not the stack. The same PartPane can exist in more than
306 :     one PartStack at a time if that part appears in more that one
307 :     perspective.<span style="font-weight: bold;"><br>
308 :     <br>
309 :     </span>
310 :     <h2><a class="mozTocH3" name="mozTocId913623"></a>3.1 An example layout</h2>
311 :     LayoutParts are best explained through example. Imagine a
312 :     WorkbenchWindow that contains custom Java and Java Browsing
313 :     perspectives that look like figure 3.1.1 and figure 3.1.2
314 :     respectively.<br>
315 :     <br>
316 :     <br>
317 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
318 :     3.1.1: Example Java Perspective</span><br>
319 :     <img alt="" src="perspective1.PNG" style="width: 571px; height: 495px;"><br>
320 :     <br>
321 :     <span style="font-weight: bold;">Figure 3.1.2: Example Java Browsing
322 :     perspective</span><br>
323 :     <img alt="" src="perspective2.PNG" style="width: 571px; height: 495px;"><br>
324 :     </div>
325 :     <br>
326 :     Assume that the window resembles Figure 3.1.1. In this case, the Java
327 :     perspective is active, the Java Browsing perspective is hidden, and the
328 :     objects are connected as shown in figure 3.1.3:<br>
329 :     <br>
330 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
331 :     3.1.3: LayoutPart instances when two perspectives are open</span><br>
332 :     <img alt="" src="perspective1_2_instances.PNG"
333 :     style="width: 555px; height: 670px;"><br>
334 :     <div style="text-align: left;"><br>
335 :     </div>
336 :     </div>
337 :     <br>
338 : sxenos 1.2 <br>
339 :     All LayoutParts have a container pointer that points to the object that
340 :     is currently managing their position. Since the same LayoutPart
341 :     instance may exist in more than one perspective at once, this pointer
342 :     points to the part's container in the currently-active perspective. In
343 :     the case of the projects view, above, the part is not in the current
344 :     perspective so its container pointer is null. When another
345 :     perspective becomes active, all the container pointers move to the new
346 :     perspective. For historical reasons, this is accomplished by setting
347 :     and
348 :     clearing the contianer pointer when the container becomes visible or
349 :     invisible. This works since only one perspective is visible at a time,
350 :     but it also means that perspectives cannot be manipulated when they are
351 :     invisible.<br>
352 : sxenos 1.1 <br>
353 :     The diagram shows the internal objects that make up the only editor.
354 :     Although this detail has been omitted for the views, they would look
355 :     similar. Each view's PartPane is owned by a part reference which may
356 : sxenos 1.2 have an associated part implementation.<br>
357 : sxenos 1.1 <br>
358 :     <h2><a class="mozTocH3" name="mozTocId994793"></a>3.2 Zoom / Unzoom
359 :     protocol<br>
360 :     </h2>
361 :     The notion of "zoom" is defined locally between a part and its
362 :     immediate container. Zoom changes are triggered bottom-up. A part asks
363 :     its parent to "zoom me", and the parent either does something with the
364 :     request or forwards the request up to its parent. Each container
365 :     determines what it means for a child to be zoomed. Once a part's zoom
366 :     state changes, its parent notifies it by calling setZoomed. The part
367 :     may in turn zoom or unzoom one or more of its children.<br>
368 :     <br>
369 :     Anything that can contain LayoutParts must implement the following
370 :     methods, to support zooming:<span style="font-family: monospace;"><br>
371 :     <br>
372 :     </span><code>&nbsp;&nbsp;&nbsp; /**<br>
373 :     &nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom in,
374 :     given an immediate child <br>
375 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
376 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toZoom part to zoom in on<br>
377 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
378 :     &nbsp;&nbsp;&nbsp; public void childRequestZoomIn(LayoutPart toZoom);<br>
379 :     &nbsp;&nbsp;&nbsp; <br>
380 :     &nbsp;&nbsp;&nbsp; /**<br>
381 :     &nbsp;&nbsp;&nbsp;&nbsp; * Called by child parts to request a zoom out<br>
382 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
383 :     &nbsp;&nbsp;&nbsp; public void childRequestZoomOut();<br>
384 :     &nbsp;&nbsp;&nbsp; <br>
385 :     &nbsp;&nbsp;&nbsp; /**<br>
386 :     &nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff the given child is obscured
387 :     due to the fact that the container is zoomed into<br>
388 :     &nbsp;&nbsp;&nbsp;&nbsp; * another part. <br>
389 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
390 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
391 :     &nbsp;&nbsp;&nbsp;&nbsp; * @return true iff the part is currently
392 :     obscured <br>
393 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
394 :     &nbsp;&nbsp;&nbsp; public boolean childObscuredByZoom(LayoutPart
395 :     toTest);<br>
396 :     &nbsp;&nbsp;&nbsp; <br>
397 :     &nbsp;&nbsp;&nbsp; /**<br>
398 :     &nbsp;&nbsp;&nbsp;&nbsp; * Returns true iff we are zoomed into the
399 :     given part, given an immediate child of this container.<br>
400 :     &nbsp;&nbsp;&nbsp;&nbsp; * <br>
401 :     &nbsp;&nbsp;&nbsp;&nbsp; * @param toTest part to test<br>
402 :     &nbsp;&nbsp;&nbsp;&nbsp; * @return true iff this contianer is currently
403 :     zooming in on the given part<br>
404 :     &nbsp;&nbsp;&nbsp;&nbsp; */<br>
405 :     &nbsp;&nbsp;&nbsp; public boolean childIsZoomed(LayoutPart toTest);<br>
406 :     </code><br>
407 :     Consider again Figure 3.1.1. If we were to double-click on the java
408 :     editor to zoom it, the LayoutParts would send messages to one another
409 :     in the following sequence. (In this diagram, each cell represents a
410 :     method call. Each column is an object. The reciever's column shows the
411 :     method name and the caller contains an arrow. Rows are in ascending
412 :     order of time.)<br>
413 :     <br>
414 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
415 :     cellspacing="2">
416 :     <tbody>
417 :     <tr>
418 :     <td style="vertical-align: top; font-weight: bold;">Java Editor
419 :     (PartPane)<br>
420 :     </td>
421 :     <td style="vertical-align: top; font-weight: bold;">PartStack<br>
422 :     </td>
423 :     <td style="vertical-align: top; font-weight: bold;">editor area
424 :     (EditorSashContainer)<br>
425 :     </td>
426 :     <td style="vertical-align: top; font-weight: bold;">ViewSashContainer<br>
427 :     </td>
428 :     </tr>
429 :     <tr>
430 :     <td style="vertical-align: top;">requestZoomIn<br>
431 :     </td>
432 :     <td style="vertical-align: top;"><br>
433 :     </td>
434 :     <td style="vertical-align: top;"><br>
435 :     </td>
436 :     <td style="vertical-align: top;"><br>
437 :     </td>
438 :     </tr>
439 :     <tr>
440 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
441 :     style="width: 42px; height: 17px;"><br>
442 :     </td>
443 :     <td style="vertical-align: top;">childRequestZoomIn(java editor)<br>
444 :     </td>
445 :     <td style="vertical-align: top;"><br>
446 :     </td>
447 :     <td style="vertical-align: top;"><br>
448 :     </td>
449 :     </tr>
450 :     <tr>
451 :     <td style="vertical-align: top;"><br>
452 :     </td>
453 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
454 :     style="width: 42px; height: 17px;"><br>
455 :     </td>
456 :     <td style="vertical-align: top;">childRequestZoomIn(java editor's
457 :     part stack)<br>
458 :     </td>
459 :     <td style="vertical-align: top;"><br>
460 :     </td>
461 :     </tr>
462 :     <tr>
463 :     <td style="vertical-align: top;"><br>
464 :     </td>
465 :     <td style="vertical-align: top;"><br>
466 :     </td>
467 :     <td style="vertical-align: top;">if there were other editor
468 :     stacks in the layout, we would call setVisible(false) on them here</td>
469 :     <td style="vertical-align: top;"><br>
470 :     </td>
471 :     </tr>
472 :     <tr>
473 :     <td style="vertical-align: top;"><br>
474 :     </td>
475 :     <td style="vertical-align: top;"><br>
476 :     </td>
477 :     <td style="vertical-align: top;">remember the partStack as the
478 :     zoomed part<br>
479 :     </td>
480 :     <td style="vertical-align: top;"><br>
481 :     </td>
482 :     </tr>
483 :     <tr>
484 :     <td style="vertical-align: top;"><br>
485 :     </td>
486 :     <td style="vertical-align: top;">setZoomed(true)<br>
487 :     </td>
488 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
489 :     style="width: 42px; height: 17px;"><br>
490 :     </td>
491 :     <td style="vertical-align: top;"><br>
492 :     </td>
493 :     </tr>
494 :     <tr>
495 :     <td style="vertical-align: top;">setZoomed(true)<br>
496 :     </td>
497 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
498 :     style="width: 42px; height: 17px;"><br>
499 :     </td>
500 :     <td style="vertical-align: top;"><br>
501 :     </td>
502 :     <td style="vertical-align: top;"><br>
503 :     </td>
504 :     </tr>
505 :     <tr>
506 :     <td style="vertical-align: top;"><br>
507 :     </td>
508 :     <td style="vertical-align: top;"><br>
509 :     </td>
510 :     <td style="vertical-align: top;"><img alt="" src="right_arrow.PNG"
511 :     style="width: 42px; height: 17px;"><br>
512 :     </td>
513 :     <td style="vertical-align: top;">childRequestZoomIn(editor area)<br>
514 :     </td>
515 :     </tr>
516 :     <tr>
517 :     <td style="vertical-align: top;"><br>
518 :     </td>
519 :     <td style="vertical-align: top;"><br>
520 :     </td>
521 :     <td style="vertical-align: top;"><br>
522 :     </td>
523 :     <td style="vertical-align: top;">call setVisible(false) on all
524 :     PartStacks for views in the perspective<br>
525 :     </td>
526 :     </tr>
527 :     <tr>
528 :     <td style="vertical-align: top;"><br>
529 :     </td>
530 :     <td style="vertical-align: top;"><br>
531 :     </td>
532 :     <td style="vertical-align: top;"><br>
533 :     </td>
534 :     <td style="vertical-align: top;">remember the editor area as the
535 :     zoomed part<br>
536 :     </td>
537 :     </tr>
538 :     <tr>
539 :     <td style="vertical-align: top;"><br>
540 :     </td>
541 :     <td style="vertical-align: top;"><br>
542 :     </td>
543 :     <td style="vertical-align: top;">setZoomed(true)<br>
544 :     </td>
545 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
546 :     style="width: 42px; height: 17px;"></td>
547 :     </tr>
548 :     <tr>
549 :     <td style="vertical-align: top;"><br>
550 :     </td>
551 :     <td style="vertical-align: top;"><br>
552 :     </td>
553 :     <td style="vertical-align: top;"><br>
554 :     </td>
555 :     <td style="vertical-align: top;">trigger a layout<br>
556 :     </td>
557 :     </tr>
558 :     <tr>
559 :     <td style="vertical-align: top;"><br>
560 :     </td>
561 :     <td style="vertical-align: top;"><br>
562 :     </td>
563 :     <td style="vertical-align: top;">setBounds(zoomed bounds)<br>
564 :     </td>
565 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
566 :     style="width: 42px; height: 17px;"></td>
567 :     </tr>
568 :     <tr>
569 :     <td style="vertical-align: top;"><br>
570 :     </td>
571 :     <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
572 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
573 :     style="width: 42px; height: 17px;"></td>
574 :     <td style="vertical-align: top;"><br>
575 :     </td>
576 :     </tr>
577 :     <tr>
578 :     <td style="vertical-align: top;">setBounds(zoomed bounds)</td>
579 :     <td style="vertical-align: top;"><img alt="" src="left_arrow.PNG"
580 :     style="width: 42px; height: 17px;"></td>
581 :     <td style="vertical-align: top;"><br>
582 :     </td>
583 :     <td style="vertical-align: top;"><br>
584 :     </td>
585 :     </tr>
586 :     <tr>
587 :     <td style="vertical-align: top;"><br>
588 :     </td>
589 :     <td style="vertical-align: top;"><br>
590 :     </td>
591 :     <td style="vertical-align: top;">trigger a layout (nothing to do)<br>
592 :     </td>
593 :     <td style="vertical-align: top;"><br>
594 :     </td>
595 :     </tr>
596 :     </tbody>
597 :     </table>
598 :     <br>
599 :     <h2><a class="mozTocH3" name="mozTocId364295"></a>3.3 Layout protocol<br>
600 :     </h2>
601 :     Every LayoutPart can specify constraints on their size. Parts specify
602 :     constraints by implementing the ISizeProvider interface. ISizeProvider
603 :     serves a similar function as the computeSize method on an SWT control,
604 :     in that the parent layout uses it to consult with the part when
605 :     computing the part's size. ISizeProvider can provide a variety of
606 :     constraints:<br>
607 :     <br>
608 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
609 :     cellspacing="2">
610 :     <tbody>
611 :     <tr>
612 :     <td style="vertical-align: top; font-weight: bold;">Constraint
613 :     type<br>
614 :     </td>
615 :     <td style="vertical-align: top; font-weight: bold;">Meaning<br>
616 :     </td>
617 :     </tr>
618 :     <tr>
619 :     <td style="vertical-align: top;">Minimum size<br>
620 :     </td>
621 :     <td style="vertical-align: top;">Given the available space along
622 :     one dimension, the part returns the minimum size that it can be
623 :     compressed to along the other dimension. For example, a stack would
624 :     typically set its minimum size to be large enough to fit its tabs. The
625 :     information about available perpendicular space could allow a stack to
626 :     have wrapping tabs and still reserve enough vertical space for the tabs
627 :     once they are wrapped to fill the available horizontal space.<br>
628 :     </td>
629 :     </tr>
630 :     <tr>
631 :     <td style="vertical-align: top;">Maximum size<br>
632 :     </td>
633 :     <td style="vertical-align: top;">Given the available space along
634 :     one dimension, the part returns the maximum size that it can utilize
635 :     along the other dimension. For example, minimized stacks are
636 :     implemented by setting their maximum size to the minimized size.
637 :     Non-minimized stacks typically have an unbounded maximum size.<br>
638 :     </td>
639 :     </tr>
640 :     <tr>
641 :     <td style="vertical-align: top;">Preferred size<br>
642 :     </td>
643 :     <td style="vertical-align: top;">Given the availble space along
644 :     one dimension and a preferred size, this returns the size closest to
645 :     the preferred size at which the part would look best. Parts can use
646 :     this to quantize their size. For example, a part can ensure that its
647 :     size is always chosen such that it can be completely filled with
648 :     toolbar icons leaving no space left over.<br>
649 :     </td>
650 :     </tr>
651 :     </tbody>
652 :     </table>
653 :     <br>
654 :     Although there are three kinds of constraints, they are all returned
655 :     using a single method. See the JavaDoc on ISizeProvider for more
656 :     information.<br>
657 :     <br>
658 :     Whenever a size constraint changes, the part notifies its contianer by
659 :     calling resizeChild(part). This tells the container to respond to the
660 :     new constraints, and to resize the child if necessary (author's note:
661 :     if this is ever exposed as API, it would be better to separate the
662 :     concerns of notifying the parent of changes and triggering a layout. In
663 :     general, it may be possible for more than one part to change without
664 :     requiring a layout between each change).<br>
665 :     <br>
666 :     <h2><a class="mozTocH3" name="mozTocId867109"></a>3.4 PartStack:
667 :     Communicating with the Presentation API<br>
668 :     </h2>
669 :     PartStack allows presentation to participate in the workbench layout.
670 :     As shown in Figure 3.4.1, it wraps a single instance of
671 :     StackPresentation, and allows it the presentation to manipulate parts
672 :     by converting each visible part into an IPresentablePart. The part
673 :     stack outlives the StackPresentation. Whenever the part stack needs
674 :     widgets, it creates the StackPresentation. If the widgets are no longer
675 :     needed, it disposes the StackPresentation and remembers its persisted
676 :     form. Whenever the PartStack persists its StackPresenation, it
677 :     remembers the presentation ID so that it will not try to restore one
678 :     StackPresentation from state saved by an incompatible presentation.<br>
679 :     <br>
680 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
681 :     3.4.1: Anatomy of PartStack</span><br>
682 :     <img alt="" src="PartStack.PNG" style="width: 430px; height: 225px;"><br>
683 :     <div style="text-align: left;"><br>
684 :     Author's note: it would be useful to update this document with a state
685 :     diagram for PartStack, and message sequence charts for initializaiton
686 :     and part activation.<br>
687 :     <br>
688 :     </div>
689 :     </div>
690 :     <h2><a class="mozTocH3" name="mozTocId854140"></a>3.5
691 :     PartSashContainer: The main workbench layout <br>
692 :     </h2>
693 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
694 :     3.5.1: PartSashContainer</span><br>
695 :     <img alt="" src="PartSashContainer.PNG"
696 :     style="width: 428px; height: 305px;"><br>
697 :     </div>
698 :     <br>
699 :     PartSashContainer implements the main layout for a perspective and the
700 :     editor area. As shown in figure 3.5.1, PartSashContainer contains a
701 :     list of children, a (possibly null) zoomed part, and a LayoutTree that
702 :     manages the actual layout. <br>
703 :     <br>
704 :     LayoutTree is a binary tree (technically, a KD tree). Each internal
705 :     node is an instance of LayoutTreeNode. It contains a draggable sash
706 :     (LayoutPartSash) that divides its area among its left and right
707 :     children. LayoutTreeNodes can be horizontal or vertical based on the
708 :     orientation of the sash. For horizontal nodes, the "left" child is on
709 :     top and the "right" child is on the bottom. Leaf nodes are instances of
710 :     LayoutTree (the base class), and they point to a LayoutPart that
711 :     occupies that region of the screen. Normally, this is a PartStack, but
712 :     in general it can be any LayoutPart. <br>
713 :     <br>
714 :     Each LayoutTree occupies a recangular region of the screen that
715 :     encompasses its children. Internal nodes keep track of an integer size
716 :     for each child (implementation note: the sizes are stored in the
717 :     associated LayoutPartSash, not the LayoutTreeNode itself). Normally,
718 :     the left and right sizes are used as a ratio for dividing up the
719 :     available space. However, when one child contains the editor area, the
720 :     other becomes "non-compressible". If one side in non-compressible, the
721 :     size value is interpreted as a fixed pixel size rather than a ratio.
722 :     When the sash is moved, the size values are set to the current pixel
723 :     sizes of the left and right children.<br>
724 :     <br>
725 :     Figure 3.5.2 shows an example LayoutTree. If this tree were rendered
726 :     in a workbench window, it would resemble Figure 3.5.3. The tall
727 :     vertical sash separating the package explorer from the editor area is
728 :     the root node. The left child is the leaf node holding the package
729 :     explorer's stack. The right node is the horizontal sash separating the
730 :     problems view from the editor area. The editor area itself is a
731 :     PartSashContainer, which has its own LayoutTree. Note that the rounded
732 :     rectangles in Figure 3.5.2 are LayoutParts. The upper portion of the
733 :     rectangle is the part type and the lower portion is some text to help
734 :     locate the part in the screenshot. In this example, every internal node
735 :     has the editor area on one side of it, so all sizes are interpreted as
736 :     pixel sizes and not ratios.<br>
737 :     <div style="text-align: center;"><span style="font-weight: bold;"></span><br>
738 :     <span style="font-weight: bold;">Figure 3.5.2: Example LayoutTree</span><br
739 :     style="font-weight: bold;">
740 :     <img alt="" src="example_LayoutTree.PNG"
741 :     style="width: 480px; height: 462px; font-weight: bold;"><br>
742 :     <span style="font-weight: bold;"><br>
743 :     Figure 3.5.3: Example perspective</span><br style="font-weight: bold;">
744 :     <img alt="" src="perspective1.PNG"
745 :     style="width: 571px; height: 495px; font-weight: bold;"><br>
746 :     </div>
747 :     <br>
748 :     Like LayoutParts, LayoutTrees also implement ISizeProvider and support
749 :     size constraints. For external nodes, the size constraints come
750 :     directly from the LayoutPart. For internal nodes, the size constraints
751 :     are computed from the child nodes as follows:<br>
752 :     <ol>
753 :     <li>When computing a constraint perpendicular to the sash, the result
754 :     is the sum of the constraints of the children plus the width of the
755 :     sash.</li>
756 :     <li>When computing a constraint parallel to the sash, the result is
757 :     the maximum of the constraints of the children<br>
758 :     </li>
759 :     </ol>
760 :     An example can help make this a little less abstract. Imagine we're
761 :     computing the minimum width for the root node in figure 3.5.1, which
762 :     is a tall vertical sash. Width measurements are perpendicular to the
763 :     sash, so we end up with case 1. The minimum width is the minimum width
764 :     of the left stack plus the sash width plus the minimum width of the
765 :     right child. This makes sense because if we made the root node any
766 :     smaller, one of the three would need to be truncated or made smaller
767 :     than their minimum size.<br>
768 :     <br>
769 :     The "right child" mentioned above is the horizontal sash separating the
770 :     problems view from the editor area. When computing its minimum width,
771 :     we hit case 2: the minimum width of a horizantal sash is the maximum of
772 :     the minimum widths of each child. Intuitively, this means that the
773 :     child with the larger minimum size will be the first to reach its
774 :     minimum when the layout gets small.<br>
775 :     <br>
776 :     <h2><a class="mozTocH2" name="mozTocId370659"></a>3.6 Drag / Drop</h2>
777 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
778 :     3.6.1: LayoutPart drop regions</span><br>
779 :     </div>
780 :     <div style="text-align: center;"><img alt="" src="drag_regions.PNG"
781 :     style="width: 571px; height: 495px;"><br>
782 :     <div style="text-align: left;"><br>
783 :     Dragging a workbench part is triggered by calling DragUtil.performDrag.
784 :     SWT controls can respond to drag / drop by registering an
785 :     IDragOverListener with DragUtil .addDragTarget. If multiple drag
786 :     listeners are registered for the same screen position, the one
787 :     associated with the most specific control gets precidence.<br>
788 :     <br>
789 :     Rather than register drag listeners directly, LayoutParts implement a
790 :     getDropTarget method. When the window recieves a drag event, it
791 :     delegates to the top-level LayoutPart's getDropTarget. Each part either
792 :     delegates to one of its children or handles the drag event directly. If
793 :     the part returns null from getDropTarget, this means that the part has
794 :     no special preference for the drop event, and the parent may provide a
795 :     default behavior. Unlike IDragOverListener, getDropTarget works
796 :     top-down. The parent may overload any drag regions that are recognized
797 :     by the child, or provide default behaviors for drag regions not
798 :     recognized by the child.<br>
799 :     <br>
800 :     Figure 3.6.1 shows regions of the workbench where LayoutParts can be
801 :     dropped. The workbench checks these regions in the following order:<br>
802 :     <br>
803 :     <table style="width: 100%; text-align: left;" border="1" cellpadding="2"
804 :     cellspacing="2">
805 :     <tbody>
806 :     <tr>
807 :     <td style="vertical-align: top;"><span
808 :     style="color: rgb(0, 51, 0);">1. green region</span><br>
809 :     </td>
810 :     <td style="vertical-align: top;">The fast view bar registers a
811 :     IDragOverListener that responds to views being dragged.<br>
812 :     </td>
813 :     </tr>
814 :     <tr>
815 :     <td style="vertical-align: top;"><span
816 :     style="background-color: rgb(0, 0, 0);"><span
817 :     style="background-color: rgb(255, 255, 255);">2. black regions</span></span><br>
818 :     </td>
819 :     <td style="vertical-align: top;">These areas are reserved by
820 :     PartSashContainer.getDropTarget. When the user drags a part over this
821 :     region, the PartSashContainer interprets this as a split and does not
822 :     ask its child to participate in the drag. This ensures that it is never
823 :     possible for the child to prevent splitting by reserving its entire
824 :     area as a drop region. The region outside the PartSashContainer's
825 :     client area is handled by an IDragOverListener registered with the
826 :     shell. This allows parts to be attached to the edge of the layout by
827 :     dragging over the window trim.<br>
828 :     </td>
829 :     </tr>
830 :     <tr>
831 :     <td style="vertical-align: top;"><span
832 :     style="color: rgb(255, 0, 0);">3. red regions</span><br>
833 :     </td>
834 :     <td style="vertical-align: top;">For most of the screen area,
835 :     PartSashContainer delegates to its child (PartStack.getDropTarget).
836 :     PartStack filters out objects that don't belong in the stack (no
837 :     editors in view stacks, etc) and delegates to the presentation
838 :     (StackPresentation.dragOver). The default presentation recognizes the
839 :     tabs and title area as drop targets, but returns null everywhere else.
840 :     This is the best practice for presentations and PartStack since it
841 :     permits PartSashContainer to extend the split regions where possible.<br>
842 :     </td>
843 :     </tr>
844 :     <tr>
845 :     <td style="vertical-align: top;"><span
846 :     style="color: rgb(0, 0, 153);">4. blue regions</span><br>
847 :     </td>
848 :     <td style="vertical-align: top;">If the child doesn't have any
849 :     particular use for the drop location, the PartSashContainer extends the
850 :     split regions. If the child allows objects of this type to be added
851 :     (determined by calling LayoutPart.allowsAdd), it uses the center of the
852 :     rectangle for stacking. Otherwise, the entire region is used for
853 :     splitting. The latter case occurs when dragging views over the editor
854 :     area or when dragging over a standalone view.<br>
855 :     </td>
856 :     </tr>
857 :     <tr>
858 :     <td style="vertical-align: top;">5. outside the window (not shown)<br>
859 :     </td>
860 :     <td style="vertical-align: top;">The workbench page registers an
861 :     IDragOverListener that responds to views being dragged outside the
862 :     workbench window, and interprets this as a detach operation.<br>
863 :     </td>
864 :     </tr>
865 :     </tbody>
866 :     </table>
867 :     <br>
868 :     By convention, all methods used for drag / drop work in display
869 :     coordinates.<br>
870 :     </div>
871 :     </div>
872 :     <h1><a class="mozTocH2" name="mozTocId438049"></a>3.0 Action Bars</h1>
873 :     Parts contribute to menus, toolbars, coolbars, popup menus, etc. using
874 :     action bars. Each action bar implements IActionBars. It is possible to
875 :     create one action bar as a child of another. In this situation, the
876 :     parent and child share the same widgets, but the child may be disabled
877 :     independently of the parent. Figure 3.0.1 shows how the workbench
878 :     action bars are
879 :     constructed. The rectangles indicate instances of IActionBars, and the
880 :     ovals indicate other entities that create or modify action bars.<br>
881 :     <br>
882 :     <div style="text-align: center;"><span style="font-weight: bold;">Figure
883 :     3.0.1: Action bar information flow</span><br>
884 :     <img alt="" src="action_bar_flow.PNG"
885 :     style="width: 800px; height: 600px;"><br>
886 :     <div style="text-align: left;"><p:colorscheme
887 :     colors="#FFFFFF,#000000,#808080,#000000,#00CC99,#3333CC,#CCCCFF,#B2B2B2"></p:colorscheme>
888 :     <div v:shape="_x0000_s2050" class="O">
889 :     <div style=""><span style="font-size: 50%;"><br>
890 :     </span><span style="font-family: Symbol; font-size: 50%;"></span><span
891 :     style="font-size: 50%;"></span><span
892 :     style="font-family: Symbol; font-size: 50%;"></span><span
893 :     style="font-size: 50%;"></span><span
894 :     style="font-family: Symbol; font-size: 50%;"></span><span
895 :     style="font-size: 50%;"></span></div>
896 :     <div style=""><span style="display: none;">
897 :     </span></div>
898 :     </div>
899 :     </div>
900 :     </div>
901 :     <br>
902 :     The workbench window has a top level IActionBars instance that
903 :     contributes to the main menubar, coolbar, etc. (this top-level object
904 :     is returned by WorkbenchWindow.getActionBars()).<br>
905 :     <br>
906 :     <h2><a class="mozTocH3" name="mozTocId808539"></a>3.1 Editor Action Bars<br>
907 :     </h2>
908 :     Each type of editor gets a reference-counted IActionBars instance that
909 :     is a child of the window's action bars. For
910 :     example, if the workbench contains 10 java editors and 10 text editors,
911 :     it will create one IActionBars to be shared among the Java editors and
912 :     another IActionBars to be shared among the text editors. Editors can
913 :     access this shared instance by calling getSite().getActionBars().
914 :     Editor action bars are initialized by an instance of
915 :     IEditorActionBarContributor, and additional actions are added by the
916 :     editorActions
917 :     extension point.<br>
918 :     <br>
919 :     The reference counted IEditorActionBars are managed by the
920 :     EditorManager, along with the IActionBarContributor.<br>
921 :     <br>
922 :     <h2><a class="mozTocH3" name="mozTocId809219"></a>3.2 Action Sets<br>
923 :     </h2>
924 :     An action set is an action bar that is identified by ID. Action sets
925 :     are contributed by the actionSets extension point, and their action
926 :     bars are a child of the workbench window's root action bars. Visibility
927 :     of action sets is controlled by the following function:<br>
928 :     <br>
929 :     <div style="margin-left: 40px;"><img alt="" src="action_set_formula.PNG"
930 :     style="width: 208px; height: 29px;"><br>
931 :     </div>
932 :     <br>
933 :     Where:<br>
934 :     <br>
935 :     <div style="margin-left: 40px;">P = set of actions enabled in the
936 :     perspective. Returned by Perspective.getAlwaysOnActionSets().
937 :     Initialized by the perspective factory, perspective extensions
938 :     extension point, and IWonkbenchPage.showActionSet.<br>
939 :     A = action sets associated with the active part (associated by the
940 :     actionSetPartAssociations extension point).<br>
941 :     E = action sets associated with the active editor (associated by the
942 :     actionSetPartAssociations extension point).<br>
943 :     D = action sets that are enabled by default (a property of the
944 :     actionSets extension markup).<br>
945 :     N = action sets that are explicitly disabled in the current
946 :     perspective. Initialized by IWorkbenchPage.hideActionSet.<br>
947 :     </div>
948 :     <br>
949 :     The sets P and N are persisted with the current perspective between
950 :     sessions. The sets A and E can change every time the active part or
951 :     editor changes.<br>
952 :     <br>
953 :     The workbench page uses the class ActionSetManager to compute action
954 :     set enablement. This class keeps two reference counts for each action
955 :     set: <br>
956 :     <ul>
957 :     <li>a "showCount" indicates how many of P, A, E, and D the action set
958 :     appears in</li>
959 :     <li>a "hideCount" indicates whether the action set appears in N</li>
960 :     </ul>
961 :     The action set is visible iff showCount is nonzero and hideCount is
962 :     zero.<br>
963 :     <br>
964 :     <h2><a class="mozTocH3" name="mozTocId846891"></a>3.3 View Actions</h2>
965 :     Each view instance is given its own IActionBars instance. Unlike editor
966 :     action bars, these are not shared and are not a child of the workbench
967 :     window's root action bars. This means that view instances can
968 :     programmatically add actions to their action bar. Additional actions
969 :     are also added to a view's action bars through the viewActions
970 :     extension point.<br>
971 :     <br>
972 :     <h1><a class="mozTocH1" name="mozTocId453994"></a>4.0 General
973 :     Conventions</h1>
974 :     This section describes coding conventions that apply to the entire
975 :     workbench.<br>
976 :     <h2><a class="mozTocH3" name="mozTocId451497"></a>4.1 Objects must not
977 :     be returned through API until they are fully initialized</h2>
978 :     Some objects require several public methods to be called in a specific
979 :     order before they are considered fully initialized. For example, to
980 :     initialize an IViewPart, it is necessary to call the constructor,
981 :     setInitializationData, init, and createPartControl before the part is
982 :     considered initialized. Until <span style="font-style: italic;">all</span>
983 :     of the above have happened successfully, it must not be possible to
984 :     reach the object through any API method.<br>
985 :     <br>
986 :     Keep in mind that the may trigger other client code during its own
987 :     initialization, so it should not even be possible for an object to find
988 :     itself during construction.<br>
989 :     <h2><a class="mozTocH3" name="mozTocId959546"></a>4.2 No method may
990 :     open a modal dialog unless its JavaDoc says so</h2>
991 :     Any method that has the possibility of opening a modal (or of calling
992 :     Display.readAndDispatch through any other means) needs to be clearly
993 :     documented. All callers of that method must be prepared to handle
994 :     background
995 :     threads running arbitrary code in *syncExecs during the method call. It
996 :     is always a bug to open a modal dialog when extending or overloading a
997 :     method unless the JavaDoc in the base class says otherwise. Permitting
998 :     opening of dialogs in a method that did not previously do so is a
999 :     breaking change for all callers of that method.<br>
1000 :     <br>
1001 :     Some common bugs:<br>
1002 :     <ul>
1003 :     <li>Views are never allowed to call MessageDialog.openError from
1004 :     their createPartControls method, especially when handling an exception.</li>
1005 :     <li>Parts can be closed in a *syncExec. If a part calls a method that
1006 :     opens dialogs, it might not still exist when the method returns. After
1007 :     calling the method, the part must check that it hasn't been disposed
1008 :     before using their widgets or accessing any members that would have
1009 :     been deallocated by the disposal.<br>
1010 :     </li>
1011 :     </ul>
1012 :     <h2><a class="mozTocH3" name="mozTocId877708"></a>4.3 Lazy creation
1013 :     should happen as late as possible<br>
1014 :     </h2>
1015 :     Part implementations should be created at the latest possible moment.
1016 :     The workbench's internal state should be restored as much as possible
1017 :     before the first object is created from an extension point. Parts
1018 :     should not be materialized until they are needed.<br>
1019 :     <h2><a class="mozTocH3" name="mozTocId758931"></a>4.4 getters should
1020 :     not modify the thing they are supposed to measure<br>
1021 :     </h2>
1022 :     This applies to any situation where there is a getter and an associated
1023 :     listener that monitors changes in the getter's value. The getter should
1024 :     never cause such a property change to be fired while computing its
1025 :     return value.<br>
1026 :     <br>
1027 :     For example, IWorkbenchPage.getActivePart() should never create the
1028 :     active part. Unless the active part already exists and a property
1029 :     change was fired to all IPartListeners, getActivePart must return null.<br>
1030 :     <br>
1031 :     <br>
1032 :     </body>
1033 :     </html>