Programming the Eclipse Workbench, Page 2
Action Bars
When exploring JFace, you learned that user-invokable functionality is encapsulated in Actions, which are visually represented by Contributions. In the Workbench, the components that expose contributions are called Action Bars. They include menus, toolbars, coolbars (a younger cousin of toolbar), and the status line. There's also the notion of "global action handlers", which give workbench parts the means to provide their own implementation of certain common actions (such as Cut, Copy, Paste, etc.) registered globally by the Workbench. Both views and editors have access to their respective action bars, though they differ in usage.
Views vs. Editors
As a user, you can probably tell the difference between views and editors with relative ease. For instance, views are usually there by default as part of the perspective, while editors are opened from one of the views. Views are usually stacked around the window's sides, while editors take up a more central location, and there is usually only one instance of the view shown at a time, but potentially multiple instances of the same editor type. Finally, each view (or a stack of them) gets its own action bars (toolbar and menu bar), while editors use the main application menu and toolbar to make contributions (you can see the action bars changing as you activate different views or editor types).
ViewPart's init
method is entirely optional, while the editor's init method must be
implemented. That is because views are left to figure out on their own
what information to display (e.g., some sort of singleton data source,
such as the Workspace, of Workbench-wide Tasks, etc.), while the editors
get their input from the client code that requests their opening; for
instance, double-clicking a file in the Resource Navigator will open the
appropriate editor with that file as its input. Thus, editors must
accept their input as part of their initialization.
Secondly, editors have a "dirty" state, which is when they may need
to be saved. Saving an editor involves storing its content in the
provided input in such a way that it can be re-opened next time around.
On the other hand, if a view wants to remember any state across its
invocations, it should store them in an IMemento, which is
a simple, hierarchical key/value pair data structure. The Workbench
stores this memento at an internal location and passes it back to the
view during its subsequent initialization.
Lastly, editors and views manage their action bars differently. While
a view gets its own instance of IActionBars (available
through its site) to which it can contribute actions directly, editors
share a single instance of action bars per editor type. This is meant to
make the management of contributions easier, given that each editor
instance may attempt to contribute the same set of actions. Instead,
editors use a helper class called the "action bar contributor"
(implementing IEditorActionBarContributor), which is
declared as part of the editor's extension. When the first instance of
the editor is created, its action bar contributor is instantiated and
used for any subsequent editor instances. The job of this class is to
contribute actions on the editor's behalf, and updated them to reflect
the currently active editor (the contributor is notified whenever the
active editor changes).
Building the List Editor
You've already developed a view in the previous article, though it did not involve action contributions. To get a better feel for how action contributions work, as well as how editors differ from views, you are going to create a simple editor with several actions contributed by its action bar contributor.
You start by creating a plug-in project, much like we did last time.
You specify that the plug-in will make contributions to the UI. This
gives the correct plug-in dependencies (org.eclipse.ui,
to be precise).
In the Plug-in Manifest Editor, declare an org.eclipse.ui.editors
extension like this: Click the Extensions tab, then the "Add..." button
in the "All Extensions" section and select "org.eclipse.ui.editors".
Click "Finish". In the editor, right-click the extension and choose "New
-> Editor". Fill out the new element's "Extension Element Details"
section with your editor's ID, name, path to an icon (located somewhere
in your plug-in), and extensions (as in "file extensions" — specify
"list" as the only recognized extension). Two remaining properties that
are required in order to proceed are "class" and "contributorClass". Those
haven't been created yet, but you can use this editor to help get
started: Clicking the "class" label (it looks like a web link) brings up
a "New Class" dialog, pre-populated with the correct superclass (org.eclipse.ui.part.EditorPart).
All you need to do is specify the name and click "Finish" to create your
editor class.
The first method to implement is init. Before it does
anything else, the editor needs to determine if it can handle the input
provided to it. In our case, the editor requires that the input
implement IPathEditorInput; if it doesn't, a PartInitException
must be thrown. You proceed by loading the editor's input into the object
model, which is ultimately what the editor uses (we will take a closer
look at it shortly). Lastly, you set the editor's site, input (the
protocol requires that we retain it), part name (you set it to the
input's name, which will usually be the filename), and a user-friendly
tooltip (which contains the full path of the input file).
Next, we implement the two familiar methods — createPartControl
and setFocus. In createPartControl, you instantiate a JFace
ListViewer, which will be sufficient for the purpose of
displaying a simple list of strings. Specify that it support
multi-item selection, which lets the user select and delete multiple
items at the same time. Then configure the viewer with a default
label provider and sorter; however, there isn't any existing content
provider that "understands" our object model, so you have to implement
your own.
