Using JViews products in Eclipse RCP applications

Installing the JViews runtime plug-in

Rogue Wave® JViews Maps provides jar files in the form of a pre-packaged Eclipse plug-in. The name of this package is ilog.views.eclipse.maps.runtime.
In order to install the Rogue Wave® JViews Eclipse plug-ins, you need to install from the local site as shown below.
For Eclipse 3.7 or later:
  1. Launch your Eclipse installation.
  2. Go to Help/Install New Software.
  3. Add a new local site: Click Add, then Local, and then specify the directory <installdir>/jviews-framework810/tools/ilog.views.eclipse.update.site
  4. Select the features you want to install, and then click Next.
In your applications, you need the ilog.views.eclipse.maps.runtime plug-in and its dependencies:
  • ilog.views.eclipse.maps.runtime
  • ilog.views.eclipse.diagrammer.runtime (optional)
  • ilog.views.eclipse.framework.runtime
  • ilog.views.eclipse.utilities.runtime

Providing access to class loaders

Many services in JViews need to look up a resource. Since the classical way to provide access to resources is a class loader, JViews uses class loaders for this purpose. But in Eclipse/RCP applications, each plug-in corresponds to a class loader, and the JViews class loader sees only its own resources, not the application resources. To fix this problem, you can register plug-in class loaders with JViews through the IlvClassLoaderUtil.registerClassLoader function. Each resource lookup then considers the registered class loaders and, if the plug-ins are configured accordingly, also considers the dependencies of the registered class loaders.
The code for doing this is usually located in a plug-in activator class. For example:
public class MyPluginActivator extends AbstractUIPlugin 
{
    /**
     * This method is called upon plugin activation
     */
    public void start(BundleContext context) throws Exception {
      super.start(context);
      IlvClassLoaderUtil.registerClassLoader(getClass().getClassLoader());
    }

    /**
     * This method is called when the plugin is stopped
     */
    public void stop(BundleContext context) throws Exception {
      super.stop(context);
      IlvClassLoaderUtil.unregisterClassLoader(getClass().getClassLoader());
    }

  }
The overriding of stop() is necessary so that, when the plug-in gets unloaded, JViews gets notified about the plug-in that is going to stop and can drop references to its resources or instances of its classes. The activator plug-in is usually also the place where IlvProductUtil.registerApplication is called.

The bridge between AWT/Swing and SWT

The Standard Widget Toolkit (SWT) is the windowing toolkit of the Eclipse development environment and the Eclipse Rich Client Platform (RCP).
JViews components are Swing components and can be embedded in an SWT window, together with other SWT or JFace controls, in three ways. Each way provides a bridge between the AWT/Swing windowing system and the SWT windowing system.
Each of the three bridges has a number of advantages and disadvantages:
  • SWT_AWT is low-level and has a number of bugs that require workarounds. It therefore requires a lot of coding to correctly implement features such as size management (because of different concepts of layout between SWT and AWT), look and feel, focus, cursors, and pop-up menus.
  • JViews IlvSwingControl handles size management and fixes some of the focus, cursor, pop-up menu problems. It also provides an emulated bridge mode on Linux/gtk that reduces the flickering when the component is resized - at the expense of more flickering when parts of the component are redrawn.
  • Albireo SwingControl also handles size management, and fixes more focus, cursor, pop-up menu problems than IlvSwingControl. It also fixes look and feel problems. However, it does not reduce the flickering.
    Albireo SwingControl also supports input methods and newer JDKs better than IlvSwingControl. Though the examples supplied with JViews use IlvSwingControl, Albireo SwingControl is likely to become increasingly appropriate in future.
To create an SWT control from an IlvScrollManagerView or IlvManagerViewPanel object, you can use the following code with IlvSwingControl:
Composite parent = ...;
IlvJManagerViewPanel mapView = new IlvJManagerViewPanel();
Control SWTmapView = new IlvSwingControl(parent, SWT.NONE, chart);
Alternatively, you can use the following code with Albireo SwingControl:
Composite parent = ...;
Control SWTmapView =
    new SwingControl(parent, SWT.NONE) {
      protected JComponent createSwingComponent() {
        return new IlvJManagerViewPanel();
      }
      public Composite getLayoutAncestor() {
        return parent;
      }
    };
Note
The IlvSwingControl bridge is not supported on all platforms. It is only supported on Windows, UNIX® with X11 (Linux, Solaris™, AIX®, HP-UX®), and MacOS X 10.54 or later with JDK 1.5.
The IlvSwingControl bridge does not support arbitrary JComponents. Essentially, components that provide text editing are not supported. See IlvSwingControl for a precise description of the limitations.

Threading modes

You can handle the SWT-Swing user interface events in one or two threads.
Note
Single-thread mode is incompatible with AWT/Swing Dialogs. If you use single-thread mode, you cannot use AWT Dialogs , Swing JDialogs , or modal JInternalFrames in your application. There are also some other limitations. See the class IlvEventThreadUtil for a precise description of the limitations.
  • Two-thread mode
    The SWT events are handled in the SWT event thread and AWT/Swing events are handled in the AWT/Swing event thread. This is the default mode.
    You can switch between the two threads by using the SWT method Display.asyncExec() and the AWT method EventQueue.invokeLater() .
    If your application uses this mode, you must be careful to:
    • Make API calls on SWT widgets only in the SWT event thread. Otherwise, you will get SWTExceptions of type ERROR_THREAD_INVALID_ACCESS .
  • Single-thread mode
    In single-thread mode, SWT and AWT/Swing events are handled in the same thread.
    Single-thread mode reduces the risk of producing deadlocks.
    Enable this mode by calling setAWTThreadRedirect or enableAWTThreadRedirect early during initialization.
    The following example shows how to enable single-thread mode:
    // Switch single-event-thread mode during a static initialization.
          static {
              IlvEventThreadUtil.enableAWTThreadRedirect();
          }