Programming the Eclipse Workbench
What makes Eclipse applications most easily recognizable is the Workbench. It is the foundation of applications such as the Eclipse IDE — the main window contains menus, toolbars, and a variety of smaller windows, some tiled, some stacked behind one another. What makes each Workbench application unique is what these windows are and what functionality they provide.
In the previous installment of the Eclipse series an Eclipse Workbench "view" was used as the host of a JFace and SWT components, but I did not go into much detail about its structure or function. In this article, the Eclipse Workbench will be explored in more detail. Specifically, the Workbench "parts" — the views and editors that make up most Workbench applications — will be reviewed.
Introduction
When you run a typical Eclipse Workbench application, such as your Eclipse IDE, you get the familiar application window with menu and toolbars at the top, status bar at the bottom, and one or more views in between. Many of these views allow you to manipulate the information they present, and perhaps edit it in specialized editors. While some tasks may be implemented as step-by-step wizards, the telltale sign of a workbench application is the ability to view and manipulate information in a variety of ways.
In this article, a simple editor is developed that lets you edit lists of strings stored in plain-text files. A JFace viewer is used to display the model. Menus are provided to allow for the addition of new entries into the list and deletion of selected entries. Also provided is support for undoing, redoing, and saving of these modifications.
To compile and run the example, you will need Eclipse SDK 3.1, available at http://www.eclipse.org/downloads. Some familiarity with the Plug-in Development Environment, JFace, and SWT is required.
Eclipse Workbench
From a user's point of view, the Workbench is a top-level application window (or several of them, in fact) with menus, toolbars, views, and editors. While this is by no means a requirement, many users have actually come to expect certain menus and views to be available in Workbench applications; for example, there is usually a File menu that allows for creation of new and opening of existing files, an Edit menu with editing actions such as Cut, Copy, and Paste, as well as a Window menu for customizing some aspects of the user interface.
From a developer's perspective, the Workbench serves as the foundation for applications that contribute their views, editors, wizards, and other components as plug-ins. You can look at the Workbench as the infrastructure that you can use to build a certain class of desktop applications. In fact, Eclipse started out as an IDE workbench suitable for developing integrated development tools, but over the years it evolved into a generic platform for Rich Client Applications (RCP). The central architectural element of these applications is precisely the Workbench (also called the Generic Workbench to differentiate it from the IDE).
Programmatically, the Workbench is represented by interface IWorkbench
,
which can be obtained as a singleton instance by calling PlatformUI.getWorkbench()
.
The Workbench provides a variety of services, most of which we won't
address here. It also provides access to its visual components, starting
with its windows; while there may be more than one window (represented
by interface IWorkbenchWindow
) in a Workbench application,
at most one can be active at any given time. Each window consists of
multiple pages (IWorkbenchPage
; although having more than
one page is rare), of which only one may be active at any given time.
At this point you may be tempted to think that switching perspectives is equivalent to flipping the window's pages. This, however, is not the case. Programmatically, a perspective just defines the page layout (which is, by the way, fully customizable by the user). When you switch perspectives, you actually apply a different layout (and a corresponding set of views) to the same page.
Finally, each workbench page consists of several "parts" — editors or views (and again, only one may be active at a time).
Each of these interfaces provides access to components and services
pertinent to their level within the hierarchy. For instance, IWorkbenchPage
allows you to show views, open editors, and manipulate the current
perspective, while IWorkenchWindow
lets you work with its
pages, and IWorbench
with windows and other Workbench-wide
services.
This hierarchy stops at IWorkbenchPart
, because this is
where customization comes to play: each view or editor implements its
own user interface and provides its own services.
Several views are considered "standard" — Properties and Content Outline in the Generic Workbench, Problems, Tasks, Bookmarks, Resource Navigator, and some others, in the IDE. Many of these expose public APIs that you can peruse in your own solutions.
Workbench Parts
While editors and views perform different functions within the
Workbench, they have much in common — they are "parts" of the
Workbench, and as such they must follow a certain protocol common to all
Workbench parts. This protocol is embodied in interface IWorkbenchPart
,
which all Workbench parts must implement.
While developing your own views or editors, you will notice that instead of directly implementing the corresponding interface, you are asked to extend an abstract base class (ViewPart
for views andEditorPart
for editors, respectively). This approach is actually quite common throughout Eclipse. It gives the API providers the flexibility to amend and evolve the API (i.e., the interface) without inadvertently breaking backward compatibility. For example, if they decide to add a new method to the interface, then all existing implementations would break, unless updated. If, however, the implementations extend an abstract class, then that class can provide the default implementation of this method, without breaking any existing subclasses.
In the previous article's example, the SuperView's createPartControl(Composite)
method was implemented in order to construct its user interface components. The
method's argument were used as the parent Composite for the viewer. In fact,
Workbench parts are essentially user interface widgets displayed and
managed by the Workbench in a specific way. Thus, this method is called
by the Workbench at the appropriate time within the part's lifecycle in
order to create its visual representation. If the part allocates any
platform resources during construction, it must dispose them in its dispose()
method.
Workbench parts are often dynamic in nature and may need to
communicate any relevant state changes to the Workbench. For this
reason, each Workbench part supports a property change notification
protocol — interested parties may add themselves as IPropertyListeners
,
which the part then notifies when one of its properties changes. Just
what these properties may be depends on the part type; one common
property shared by both views and editors is their title.
The Workbench supplies each of its parts with instance-specific
services by means of a "site" (IWorkbenchPartSite
) — the
primary interface between the part and the Workbench. The way in which
views and editors are supplied with it differs, but what they do have in
common is that both are initialized with a site provided by the
Workbench before their user interfaces may be constructed (views
actually get a view-specific subtype of the site, as do the editors).
Page 1 of 3