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

Parent Directory Parent Directory | Revision Log Revision Log


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