### org.eclipse.ui.views

A view is a workbench part that can navigate a hierarchy of information or display properties for an object. Only one instance of any given view is open in a workbench page. When the user makes selections or other changes in a view, those changes are immediately reflected in the workbench. Views are often provided to support a corresponding editor. For example, an outline view shows a structured view of the information in an editor. A properties view shows the properties of an object that is currently being edited.

The extension point org.eclipse.ui.views allows plug-ins to add views to the workbench. Plug-ins that contribute a view must register the view in their plugin.xml file and provide configuration information about the view, such as its implementation class, the category (or group) of views to which it belongs, and the name and icon that should be used to describe the view in menus and labels.

The interface for views is defined in IViewPart, but plug-ins can choose to extend the ViewPart class rather than implement an IViewPart from scratch.

We implemented a minimal view extension in the hello world example. Now we'll look at one that is aware of other workbench views and responds to user navigation and selection changes in the workbench. First, let's take a look at the declaration of the extension in the plugin.xml.

    <extension
       point="org.eclipse.ui.views">
    	<category
    	   id="org.eclipse.ui.examples.readmetool"
    	   name="%Views.category">
    	</category>
    	<view
     	   id="org.eclipse.ui.examples.readmetool.views.SectionsView"
    	   name="%Views.ReadmeSections"
    	   icon="icons/view16/sections.gif"
    	   category="org.eclipse.ui.examples.readmetool"
    	   class="org.eclipse.ui.examples.readmetool.ReadmeSectionsView">
    	</view>
    </extension>

This should look pretty familiar. We see that a new view, ReadmeSectionsView, is contributed to the workbench. The view id, name, and category are specified as we've seen before. An icon is also provided for the view, using a path relative to the plug-in's installation directory.

Let's look at the ReadmeSectionsView. You can show any view in the workbench by choosing Window->Show View->Other... and selecting the view from the Show View list.

When we show the ReadmeSectionsView, a view with a list in it pops up. The list is empty unless we click on a file with an extension of .readme, in which case the list is populated with sections from the readme file.

How does the plug-in recognize the readme file and how did it know about selection changes? If we can track down the answers to these questions, we are well on our way to understanding how to build integrated workbench plug-ins.

We'll start with the familiar createPartControl method. As we saw in the Hello World example, this is where the widgets that represent a view are created. We'll ignore some of the code to get started.

       public void createPartControl(Composite parent) {
          viewer = new ListViewer(parent);
          ...
          // add myself as a global selection listener
          getSite().getPage().addSelectionListener(this);

          // prime the selection
          selectionChanged(null, getSite().getPage().getSelection());
       }

The view creates and stores a ListViewer and registers itself as a selection listener on its page. It obtains the page from an IViewSite, which contains information about the view's context, such as its workbench window, its containing page, and its plug-in. When we are notified of a selection change, what happens? The following code is executed:

       public void selectionChanged(IWorkbenchPart part, ISelection sel) {
          //if the selection is a readme file, get its sections.
          AdaptableList input = ReadmeModelFactory.getInstance().getSections(sel);
          viewer.setInput(input);
       }

It looks like the ReadmeModelFactory class is responsible for turning the selection into readme sections and these sections are input for the viewer that we created in the createPartControl method.

But how did the viewer populate its list widgets? For now, let's assume that once the viewer was told its input element, it knew how to populate its list widget with the information - it is a ListViewer, after all. If you must know right now what this viewer is all about, go to Viewers.

We still do not know how readme files are detected or where the file's section information comes from. A quick look at the ReadmeModelFactory sheds some light.

       public AdaptableList getSections(ISelection sel) {
          // If sel is not a structured selection just return.
          if (!(sel instanceof IStructuredSelection))
             return null;
          IStructuredSelection structured = (IStructuredSelection)sel;

          //if the selection is a readme file, get its sections.
          Object object = structured.getFirstElement();
          if (object instanceof IFile) {
             IFile file = (IFile) object;
             String extension = file.getFileExtension();
             if (extension != null && extension.equals(IReadmeConstants.EXTENSION)) {
                return getSections(file);
             }
          }

          //the selected object is not a readme file
          return null;
       }

We check the selection to see if it is a structured (multiple) selection. (The concept of a structured selection comes from JFace viewers.) For the first object in the selection, we check to see whether it is a file (IFile) resource. If it is, we check its extension to see if it matches the ".readme" extension. Once we know we have a readme file, we can use other methods to parse the sections. You can browse the rest of ReadmeModelFactory, MarkElement, and DefaultSectionsParser for the details about the file parsing.

We've covered a lot of common workbench concepts by studying this extension. Now we'll move on to some other workbench extensions and examine how your plug-in can further contribute to the workbench UI.