Chapter 10. Perspectives and Views

This chapter answers questions about two central concepts in the Eclipse Platform UI. Perspectives define the set of actions and parts that appear in a workbench window and specify the initial size and position of views within that window. Views are the draggable parts that make up the bulk of a workbench window’s contents. This chapter does not deal with any specific perspectives or views, but with questions that arise when you implement your own perspectives and views.

FAQ 190: How do I create a new perspective?

Use the org.eclipse.ui.perspectives extension point. This extension point allows you to define an initial layout of views relative to the editor area, in addition to specifying the contents of the window’s menu and toolbars. Everything you can do from Window > Customize Perspective can be done programmatically with the perspectives extension point. The steps for creating your own perspective are well described in the Platform Plug-in Developer Guide.

Note

FAQ 190: How do I create a new perspective?

eclipse.org article “Using Perspectives in the Eclipse UI”

Go to Platform Plug-in Developer Guide > Programmer’s Guide > Plugging into the workbench > Perspectives

FAQ 191: How can I add my views and actions to an existing perspective?

Use the org.eclipse.ui.perspectiveExtensions extension point. This extension point allows a third party to define the position of views in another plug-in’s perspective. This extension point can also be used to add actions to the menus and toolbars. An interesting attribute of this extension point is that it is purely declarative. No Java code is associated with a perspective extension; it is purely XML markup. The mechanics of writing perspective extensions are well described in the Platform Plug-in Developer Guide.

Note

FAQ 191: How can I add my views and actions to an existing perspective?

eclipse.org article “Using Perspectives in the Eclipse UI”

Go to Platform Plug-in Developer Guide > Programmer’s Guide > Plugging into the workbench > Perspectives

FAQ 192: How do I show a given perspective?

Two APIs show a perspective: IWorkbench.showPerspective and IWorkbenchPage.setPerspective. You should generally use the first of these two because it will honor the user’s preference on whether perspectives should be opened in the same window or in a separate window. Here’s a quick sample snippet that opens the perspective with ID perspectiveID:

IWorkbench workbench = PlatformUI.getWorkbench();
workbench.showPerspective(perspectiveID,
   workbench.getActiveWorkbenchWindow());

Usually, the method getActiveWorkbenchWindow comes with the caveat that you must check for a null return value. In this case, null is acceptable: The showPerspective method uses the window parameter as a hint about what window to show the perspective in. If a null window is passed, it will pick an appropriate existing window or open a new one.

FAQ 193: What is the difference between a perspective and a workbench page?

The workbench page is the main body of a workbench window: between the toolbar and the status line, the area that contains views and editors. In Eclipse 1.0, each workbench window could have multiple pages, but this is no longer the case. The workbench page can have one or more perspectives associated with it that define the layout of the views and editors in the page. Each workbench page has at most one instance of each kind of view and one editor per unique editor input. When the perspective is changed, the position and visibility of views and editors change, but the set of open views and editors does not change.

Note

FAQ 193: What is the difference between a perspective and a workbench page?

FAQ 167 Pages, parts, sites, windows: What is all this stuff?

FAQ 194: How do I create fixed views and perspectives?

New APIs in Eclipse 3.0 allow perspectives more control over how their views are presented. These APIs are useful in RCP applications that want different view-presentation models. The IPageLayout interface, provided when your perspective factory is creating its initial layout, has methods for customizing how views will be presented in that perspective. The setFixed method on IPageLayout indicates that a perspective should be fixed. In a fixed perspective, views and editors cannot be moved or zoomed by the user.

A stand-alone view, created with the method addStandaloneView, cannot be stacked together with other views and can optionally hide its title bar. A view with its title bar hidden cannot be closed, minimized, or moved. For further control over whether views can be closed or moved, you can obtain an IViewLayout instance for any view in the perspective. Following is an example of a fixed perspective that creates a stand-alone view above the editor area that cannot be moved or closed.

class RecipePerspective implements IPerspectiveFactory {
   public void createInitialLayout(IPageLayout page) {
      page.setEditorAreaVisible(true);
      page.setFixed(true);
      page.addStandaloneView(
         RecipePlugin.VIEW_CATEGORIES,
         false, IPageLayout.TOP, 0.2f,
         IPageLayout.ID_EDITOR_AREA);
      IViewLayout view = page.getViewLayout(
         RecipePlugin.VIEW_CATEGORIES);
      view.setCloseable(false);
      view.setMoveable(false);
   }
}

You can add fixed and stand-alone views to perspectives from other plug-ins using the perspectiveExtensions extension point. See the extension point documentation for more details.

Note

FAQ 194: How do I create fixed views and perspectives?

FAQ 191 How can I add my views and actions to an existing perspective?

FAQ 199 Why can’t I control when, where, and how my view is presented?

FAQ 195: What is a view?

Views are one of the two kinds of parts that make up a workbench window. At their most basic, views are simply a subclass of the SWT Composite class, containing arbitrary controls below a title bar. The title bar contains the view name, an area for toolbar buttons, and one or two drop-down menus. The drop-down menu on the upper left is simply the standard shell menu with actions for moving, resizing, and closing the view. The menu on the upper right and the button area are the view’s action bar and may contain arbitrary actions defined by the implementer of that view.

A view interacts with the rest of the workbench via its site. Browse through the interfaces IViewSite, IWorkbenchPartSite, and IWorkbenchSite to see what site services are available to a view.

Note

FAQ 195: What is a view?

FAQ 146 What is a viewer?

FAQ 167 Pages, parts, sites, windows: What is all this stuff?

FAQ 196 What is the difference between a view and a viewer?

FAQ 206 What is the difference between a view and an editor?

FAQ 196: What is the difference between a view and a viewer?

An unfortunate choice of terminology resulted in one of the basic building blocks of the Eclipse workbench having a remarkably similar name to a central construct in JFace. The apprentice Eclipse programmer often falls into the trap of using the terms view and viewer interchangeably and then becomes horribly confused by conflicting accounts of their usage. In reality, they are completely different and fundamentally unrelated constructs. As outlined earlier, JFace viewers are SWT widget adapters that, among other things, perform transformations between model objects and view objects. Views, on the other hand, are one of the two kinds of visible parts that make up a workbench window.

To confuse matters, a view often contains a viewer. The Navigator view, for example, contains a tree viewer. This is not always true, however. A view may contain no viewers, or it may contains several viewers. Viewers can also appear outside of views; for example, in dialogs or editors. In short, views and viewers have no fixed relationship. To put it mathematically, they are orthogonal concepts that often intersect.

Note

FAQ 196: What is the difference between a view and a viewer?

FAQ 146 What is a viewer?

FAQ 195 What is a view?

FAQ 197: How do I create my own view?

The simplest way is to use the PDE wizard to create a view example and go from there. Select File > New > Other... > Plug-in Development > Plug-in Project, and choose a name and ID for your plug-in. Then, in the plug-in code generator wizard page, choose Plug-in with a view. Look at the generated plugin.xml file for the generated extension point code.

To add a view to an existing plug-in, edit your plugin.xml with the Manifest Editor, choose the Extensions tab, click Add..., select Extension Templates, and choose Sample View.

To see how other plug-ins use views, search on the org.eclipse.ui.views extension point in the Search dialog. Choose the Plug-in Search tab, and enter the name of the extension point.

FAQ 198: How do I set the size or position of my view?

The short answer is that you can’t always control the size and position of your view. If you create your own perspective, you can specify the initial size and position of the view relative to other views. Once the perspective has been opened, the user is free to move the view elsewhere and change its size. At this point, you no longer have control over the view’s size and position.

In a similar manner, you can influence the initial size and position of your view in other perspectives by using the perspectiveExtensions extension point. As with perspectives, this extension point allows you to specify the size and position of your view relative to other views that are known to be in that perspective. Note that you shouldn’t generally make your view appear by default in perspectives provided by other plug-ins. If many plug-ins did this, the host perspective would quickly become cluttered and difficult to use. To ensure that your view does not appear by default, specify the attribute visible=“false” in your extension declaration.

Note

FAQ 198: How do I set the size or position of my view?

FAQ 190 How do I create a new perspective?

FAQ 191 How can I add my views and actions to an existing perspective?

FAQ 199 Why can’t I control when, where, and how my view is presented?

FAQ 199: Why can’t I control when, where, and how my view is presented?

Plug-in writers implementing views are often frustrated by their lack of control over when and how their views are presented to the user. Common questions include the following:

  • How do I control when users can open my view?

  • How do I ensure that my two views are always open at the same time?

  • How do I make a view appear in a floating shell or dialog?

  • How can I ensure that my view is a certain size?

The answer to such questions is more philosophical than some plug-in writers would like.

As an integration platform, Eclipse must balance between customizability and conformity. The platform needs to be customizable in order to adapt to the unforeseeable needs of plug-ins being integrated into the platform. On the other hand, in order to provide a coherent user experience, components need to be presented consistently. The ultimate goal is for the user to perceive the end product as a coherent and self-consistent application rather than as a collection of isolated components that don’t know anything about one another.

The platform seeks this balance with views by giving the view implementer limited control over how views are presented. The view writer has control over the body of the view but little or no control over where the view appears in the workbench page, what size it has, and when it is opened or closed. This approach prevents individual views from exerting too much control over the rest of the workbench window. Because the view implementer can never foresee exactly what configuration of views and editors the end user may want to have open, it cannot make reasonable choices about what happens beyond its borders. Only users are in a position to know exactly what kind of layout they want.

Giving limited power to individual views also gives the platform the flexibility to change its look and feel between releases without breaking API compatibility. For example, version 1.0 of the platform allowed views to float as separate shells outside the workbench window, but this capability was removed in version 2.0. The API designers expose only functionality that they are confident can be supported for the long term.

Note

FAQ 199: Why can’t I control when, where, and how my view is presented?

FAQ 194 How do I create fixed views and perspectives?

How will my view show up in the Show View menu?

All views show up automatically under Show View > Other.... The category attribute in your view extension declaration defines what folder your view appears under in this dialog. And no, you cannot prevent your view from appearing in this dialog.

The active perspective defines the set of views that appear in the Show View submenu. If you define your own perspective or a perspective extension to another plug-in’s perspective, you get to contribute entries to this list. The user is always allowed to customize the perspective to change the set of views that appear here.

Note

How will my view show up in the Show View menu?

FAQ 190 How do I create a new perspective?

FAQ 191 How can I add my views and actions to an existing perspective?

FAQ 201: How do I make my view appear in the Show In menu?

The Navigate > Show In menu displays a list of views that the user can jump to from the active editor or view. This facility allows linking between views and editors that may not even know about each other. The active perspective gets to decide what views appear in this list, but you can contribute your views to this list by using the perspectiveExtensions extension point. Here is an extension definition that adds the bookshelf example Chapters view to the Show In menu of the Resource perspective:

<extension
   point="org.eclipse.ui.perspectiveExtensions">
   <perspectiveExtension targetID =
      "org.eclipse.ui.resourcePerspective">
   <showInPart id = "org.eclipse.faq.examples.ChaptersView"/>
   </perspectiveExtension>
</extension>

The Chapters view then implements the show method from the IShowInTarget interface. This method is called by the platform when the user selects the view in the Show In menu. The method has a parameter, ShowInContext, that is passed from the view that is the source of the Show In action. The method must return true if it accepts the context as a valid input for that view and false otherwise. Here is the example implementation from the Chapters view:

public boolean show(ShowInContext context) {
   if (viewer == null || context == null)
      return false;
   ISelection sel = context.getSelection();
   if (sel instanceof IStructuredSelection) {
      IStructuredSelection ss = (IStructuredSelection)sel;
      Object first = ss.getFirstElement();
      if (first instanceof Book) {
         viewer.setInput(first);
         return true;
      }
   }
   return false;
}

A view that wants to act as a source for the Show In menu must implement IShowInSource. This interface defines the method getShowInContext, which creates the context object to be passed to the target. In our bookshelf example, the Books view will act as a Show In source by implementing the getShowInContext method as follows:

public ShowInContext getShowInContext() {
   return new ShowInContext(null, viewer.getSelection());
}

The context instance may contain an input object and a selection. If your view needs to provide extra context information, you can create your own ShowInContext subclass that carries additional data. Of course, only views that know about that special subclass will be able to make use of the extra information, so you should also provide the basic context information if you can.

Note

FAQ 201: How do I make my view appear in the Show In menu?

FAQ 191 How can I add my views and actions to an existing perspective?

FAQ 202: How do I add actions to a view’s menu and toolbar?

Each view has a drop-down menu in two locations:

  • Under the icon on the view’s tab itemThis menu contains layout and view-manipulation actions. You don’t have any control over this menu; its actions are all added by the platform.

  • In the view’s toolbarThe drop-down menu on the right-hand side, a small downward-pointing triangle, is controlled by your view. This menu will exist only if you add actions to it.

Actions are added to the menu and toolbar by using the IActionBars interface. This interface is used to access the standard JFace menu and toolbar manager objects used for creating menus throughout Eclipse.

The following code, usually invoked from the view’s createPartControl method, adds a single action to the view’s menu and toolbar:

Action action = ...;
IActionBars actionBars = getViewSite().getActionBars();
IMenuManager dropDownMenu = actionBars.getMenuManager();
IToolBarManager toolBar = actionBars.getToolBarManager();
dropDownMenu.add(action);
toolBar.add(action);

Note

In the view’s toolbar.

FAQ 232 How do I build menus and toolbars programmatically?

FAQ 203: How do I make a view respond to selection changes in another view?

Views can be made to respond to selection changes in other views with org.eclipse.ui.ISelectionService. A selection service allows views to work together without having to couple their views tightly. It also adds flexibility and extensibility to your design.

Say you have one view that shows a list of books and another view that displays the chapters within a book. When the user selects a book in the first view, you want to display the chapters of that book in the second view. Now say that another plug-in is installed that provides a graphical Book view and a Metrics view that displays various metrics about a selected book. If your original views were linked using explicit coupling, selection changes in your Books view would not activate the Metrics view. Conversely, selection changes in the graphical Books view would not correctly update your Chapters view. Using the selection service gives an opportunity for other plug-ins to connect to your view by listening to your selection changes or providing selections that your views can respond to.

Follow three simple steps to make use of an ISelectionService in your views. First, find an appropriate selection service. Two selection services are available to a view: window selection and page selection. The first is used for tracking selection changes in an entire workbench window, and the second is constrained to selection changes within a single page. Typically, you want to track selection changes only within the current page. Because only one page is visible at a time anyway, responding to selection changes in other pages is generally a waste of effort. The window-selection service is accessible via IWorkbenchWindow.getSelectionService. The page-selection service extends the ISelectionService interface and is available from IWorkbenchPage.

Second, register the view-selection provider with the selection service. The view that wants to broadcast selection changes simply has to register itself with the ISelectionService by supplying an implementation of org.eclipse.jface.viewers ISelectionProvider. In most cases, your view will contain a JFace viewer, all of which implement ISelectionProvider directly. If your view does not contain a viewer, you will have to implement the ISelectionProvider interface directly. Here is a sample of a view’s createPartControl method, which creates a viewer and then registers it with the page-selection service:

public void createPartControl(Composite parent) {
   int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL;
   viewer = new TableViewer(parent, style);
   getSite().setSelectionProvider(viewer);
   ...
}

The final step is to register a selection listener with the selection service. The view that wants to respond to selection changes must register an implementation of org.eclipse.ui ISelectionListener with the selection service. The following example defines the Chapters view described earlier. This view responds to selection changes where the selection is a book and displays the chapters of that book. It is important for your selection listener to ignore selections that it does not understand. The selection service will be broadcasting all kinds of selection changes that are not relevant to your view, so you need to listen selectively.

public class ChaptersView extends ViewPart {
   private TableViewer viewer;
   ISelectionListener listener = new ISelectionListener() {
      public void selectionChanged(IWorkbenchPart part,
         ISelection sel) {
         if (!(sel instanceof IStructuredSelection))
            return;
         IStructuredSelection ss = (IStructuredSelection) sel;
         Object o = ss.getFirstElement();
         if (o instanceof Book)
            viewer.setInput(ss.size()==1 ? o : null);
      }
   };
   public void createPartControl(Composite parent) {
      ...

      getSite().getPage().addSelectionListener(listener);
   }
   public void dispose() {
      getSite().getPage().removeSelectionListener(listener);
   }
}

Again, note how this example completely ignores selections that don’t contain books. If the selection contains a single book, the view will display its chapters. If the selection contains several books, it will display nothing. Also note in this example that the view is responsible for removing the selection listener when it closes. As a general rule with listeners, the code for adding a listener should never be very far from the code for removing the listener. If you forget to remove your listener when the view is closed, your selection listener will cause errors later on.

Note

FAQ 203: How do I make a view respond to selection changes in another view?

FAQ 168 How do I find out what object is selected?

FAQ 204: How does a view persist its state between sessions?

Storing view state is done in two commons ways, depending on whether you want to store settings between workbench sessions or across invocations of your view. The first of these facilities is found directly on IViewPart. When the workbench is shut down, the method saveState is called on all open views. The parameter to this method is an IMemento, a simple data structure that stores hierarchies of nodes containing numbers and strings.

Here is an example from the recipe application in the FAQ examples, where a view is persisting the current selection of a list viewer in a memento:

private static final String STORE_SELECTION =
   "ShoppingList.SELECTION";
public void saveState(IMemento memento) {
   super.saveState(memento);
   ISelection sel = viewer.getSelection();
   IStructuredSelection ss = (IStructuredSelection) sel;
   StringBuffer buf = new StringBuffer();
   for (Iterator it = ss.iterator(); it.hasNext();) {
      buf.append(it.next());
      buf.append(','),
   }

   memento.putString(STORE_SELECTION, buf.toString());
}

When the workbench is reopened, the method init(IViewSite, IMemento) is called the first time each view becomes visible. The IMemento will contain all the information that was added to it when the workbench was shut down. Note that init is called before the createPartControl method, so you will not be able to restore widget state directly from the init method. You can store the IMemento instance in a field and restore state later on when your widgets have been created. Continuing this example, here is the code for restoring the viewer selection when the view is reopened:

private IMemento memento;
...
public void init(IViewSite site, IMemento memento)
   throws PartInitException {
   super.init(site, memento);
   this.memento = memento;
}
public void createPartControl(Composite parent) {
   //create widgets ...
   if (memento == null) return;
   String value = memento.getString(STORE_SELECTION);
   if (value == null) return;
   IStructuredSelection ss = new StructuredSelection(
      value.split(","));
   viewer.setSelection(ss);
}

Note that the IMemento instance can be null if the view state was not saved from a previous session; for example, when the view is first created.

Another mechanism for persisting view state is the JFace IDialogSettings facility. The advantage of dialog settings over the view save/init mechanism is that you can control when settings are persisted. The saveState method is called only if your view is open when the workbench shuts down, so it is not useful for storing view state when the view is closed by the user. Dialog settings, on the other hand, can be changed and persisted whenever you want.

Views commonly use a combination of both dialog settings and a memento for persisting view state. Important settings, such as filters, sorters, and other view preferences, will be stored as dialog settings; more transient attributes, such as selection and expansion state, will be stored in the memento only when the workbench is being shut down.

Note

FAQ 204: How does a view persist its state between sessions?

FAQ 166 How do I save settings for a dialog or wizard?

FAQ 205: How do I open multiple instances of the same view?

Eclipse 3.0 lifts the restriction of allowing only a single instance of each view type. You can now open any number of copies of a given view. Each copy needs a secondary ID to disambiguate the view reference. Here is a snippet that opens two copies of the Books view from the FAQ Examples plug-in:

IWorkbenchPage page = ...;
String id = "org.eclipse.faq.examples.BooksView";
page.showView(id, "1", IWorkbenchPage.VIEW_VISIBLE);
page.showView(id, "2", IWorkbenchPage.VIEW_ACTIVATE);

The first parameter is the view ID from the extension definition in the plugin.xml file. The second parameter is an arbitrary string that is used to identify that particular copy of the view. Finally, the third parameter is used to specify whether the view should be created but not made visible (VIEW_CREATE), created and made visible but not made active (VIEW_VISIBLE), or created and made visible and active (VIEW_ACTIVATE).

Once multiple copies of a view exist, they can be located by using the method IWorkbenchPage.findViewReference, where the primary and secondary view IDs are passed as a parameter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.17.12