Developing a client application using the Eclipse RCP

The best way of showing the basics of client application development with the Eclipse RCP is by using an example. As we have seen in Chapter 8, Eclipse Development, Eclipse contains useful plugin project templates that can get you going into plugin development in no time. The same goes for RCP applications. Let's create a new RCP application project using a template to have an idea of what a basic RCP application project looks like.

Creating a new client application project using a template

The process of creating an RCP application is very similar to that of creating a plugin project. Navigate to File | New | Other, and in the wizard window, select Plug-in Project. Click on Next. In the next wizard window, fill in the project's Name field with something such as HelloRCP, and then click on Next. In the next window, select Yes for the Would you like to create a rich client application question, as shown in the following screenshot:

Creating a new client application project using a template

The next wizard window contains the available RCP templates. Let's use the RCP application with a view template. The last page contains some basic information required by this template. Let's leave the default values and click on Finish. You will be asked if you want to switch to the Plug-in Development perspective at this point if you're not already using it. This perspective adds views and menu entries that can be very useful for plugin development, so go ahead and choose Yes. The project will appear in the Package Explorer window and the Plug-in Manifest Editor window will be opened.

If you take a look at the project's contents, you will notice that they are very similar to the contents of a Plug-in project. This is because an RCP application is actually a plugin. The implementation of the org.eclipse.core.runtime.applications extension point, which can be verified in the Extensions tab of the Plug-in Manifest Editor window, sets it apart from a regular plugin project. Notice that the Application element points to a class named Application.

A closer look at the generated source code

We will now look at the content of classes generated by the template to understand what they do and why they are there. Let's start with the Application.java source file. As you can see, this class is an implementation of the IApplication interface, which contains the following two methods:

  public Object start(IApplicationContext context) {
    Display display = PlatformUI.createDisplay();
    try {
      int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
      if (returnCode == PlatformUI.RETURN_RESTART) {
        return IApplication.EXIT_RESTART;
      }
      return IApplication.EXIT_OK;
    } finally {
      display.dispose();
    }
  }

And

  /* (non-Javadoc)
   * @see org.eclipse.equinox.app.IApplication#stop()
   */
  public void stop() {
    if (!PlatformUI.isWorkbenchRunning())
      return;
    final IWorkbench workbench = PlatformUI.getWorkbench();
    final Display display = workbench.getDisplay();
    display.syncExec(new Runnable() {
      public void run() {
        if (!display.isDisposed())
          workbench.close();
      }
    });
  }

As the names imply, the start method is called during the application's startup, and the stop method is called when the application is stopped. The start method can return any type of object, including integers, as is the case with the Application implementation. This is a very basic implementation that simply creates a new Display object and calls the static PlatformUI.createAndRunWorkbench method. This method receives a WorkbenchAdvisor object as a parameter. This object allows you to configure some basic aspects of your application's look and feel. Every RCP application must implement a WorkbenchAdvisor object. The Display object manages the connection between SWT and the operating system. For most RCP applications, you won't need much more than these in the start method to get it going. The stop method simply closes the workbench created during the start method.

Now let's take a closer look at the generated extension of the WorkbenchAdvisor class, the ApplicationWorkbenchAdvisor extension:

public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {

  private static final String PERSPECTIVE_ID = "HelloRCP.perspective";

  public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
      IWorkbenchWindowConfigurer configurer) {
    return new ApplicationWorkbenchWindowAdvisor(configurer);
  }

  public String getInitialWindowPerspectiveId() {
    return PERSPECTIVE_ID;
  }

}

The getInitialWindowPerspectiveId method determines which perspective will be displayed when a new window of our application is opened. The CreateWorkbenchWindowAdvisor method is responsible for instantiating and returning a WorkbenchWindowAdvisor object, which configures the application window itself. Our implementation returns an instance of ApplicationWorkbenchWindowAdvisor extension, which extends WorkbenchWindowAdvisor object. Let's take a look at its implementation:

public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

  public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
    super(configurer);
  }

  public ActionBarAdvisor createActionBarAdvisor(
      IActionBarConfigurer configurer) {
    return new ApplicationActionBarAdvisor(configurer);
  }

  public void preWindowOpen() {
    IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
    configurer.setInitialSize(new Point(400, 300));
    configurer.setShowCoolBar(false);
    configurer.setShowStatusLine(false);
    configurer.setTitle("RCP Application");
  }
}

The preWindowOpen method implementation calls getWindowConfigurer and performs some actions on the IworkbenchWindowConfigurer configurer, such as setting an initial size for the application window, disabling the coolbar and status line, and setting a title for the application. The createActionBarAdvisor method instantiates and returns ApplicationActionBarAdvisor, which extends ActionBarAdvisor. ActionBarAdvisor creates, adds, and disposes the JFace actions of a workbench window. A JFace action is a command that can be triggered by the end user utilizing UI elements, such as buttons, menu items, and items in the toolbar. The ApplicationActionBarAdvisor implementation doesn't modify ActionBarAdvisor's behavior.

Now, let's go back to the Plug-in Manifest Editor window and see what other plugins are required to build a fully functional RCP application. As we said in the beginning of the chapter, an RCP application is something like an Eclipse instance stripped of every Eclipse graphical element. This means you must create these elements if you want your application to function properly. The first thing we need is a perspective, which is created by implementing the org.eclipse.ui.perspectives extension point. The perspective element contains an ID, which must be unique across the applications, must be a user-friendly name that will be displayed in the interface, and a class. Let's take a look at the Perspective class code:

public class Perspective implements IPerspectiveFactory {

  public void createInitialLayout(IPageLayout layout) {
    layout.setEditorAreaVisible(false);
    layout.setFixed(true);
    
  }
}

The code shows us that perspective classes must implement the IPerspectiveFactory interface, which contains the createInitialLayout method. The implementation generated by the template simply removes the editor area from the application and disallows users to modify the view's size and placement by calling the setFixed method. The editor area is a space in the center of the application's window that is reserved for editors. Any other views will be rendered either below, to the left of, or to the right of this area. The editor area is disabled for our application because it doesn't have any editors.

This method could also be used to add the views to the perspective by calling the layout.addView method. However, the code generated by the template uses a different approach. Go back to the Plug-in Manifest Editor window and take a look at the org.eclipse.ui.perspectiveExtensions implementation. This extension point allows you to add a view to an existing perspective. This approach is generally used when you want to add a view to a perspective that wasn't developed by you. In this case, you wouldn't have access to the IPerspectiveFactory implementation to add a layout.addView call to the createInitialLayout implementation.

The perspectiveExtension element is where you define the ID of the perspective that will receive the view. This field allows using the * (asterisk) character, which will cause the view to be added to every perspective that matches the pattern. For example, org.eclipse.jdt.* would include the view in every Java Development Tools (JDT) perspective. This is another benefit of using the perspectiveExtensions extension point instead of calling layout.addView in the IPerspectiveFactory implementation. It simplifies the task of managing the perspectives into which the view is added. In our example, targetID is simply *, which means that in HelloRCP.view, the view will be added to every perspective available (there's only one perspective in our application).

Speaking of the view, let's take a look at the org.eclipse.ui.views extension. This is a simple view, just like the one we created in Chapter 8, Eclipse Development. It points to a View class that extends the ViewPart abstract class. The createPartControl method instantiates a TableViewer object and associates a content provider and a label provider to it. We will explore the concepts of a label and content providers when we expand this example in the later sections. TableViewer is a JFace widget that displays content in a table-like list, similar to the one utilized in JDT's Problems view.

The last extension point that our RCP application implement is org.eclipse.ui.menus. It simply provides a File menu contribution that contains an Exit entry. This entry runs the org.eclipse.ui.file.exit command, which causes the program to exit.

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

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