How to Create a Custom Widget for RAP?

Like in SWT, you can also create custom widgets to extend the RAP widget set to your needs. Examples range from simple compositions of existing controls to complex widgets such as custom tab folders, or animated graphs and charts.

There are different types of custom widgets which will be described below. But no matter which type of custom widget you implement, you will end up with a RAP widget that has an SWT-like API and inherits some methods from an SWT super class. Therefore you should make yourself familiar with some important rules of SWT before you get started.

We highly recommend to read this article by the creators of SWT. [1]
The RAP Wiki may cover more recent issues regarding custom widgets. [2]

Different types of custom widgets

These types differ a lot with regard to the features they support, the dependency on a certain platform, and also the effort and knowledge it takes to create them.

Compound widgets

These are the simplest ones. Compound widgets are compositions of existing SWT/RAP widgets. These widgets have to extend Composite. There is no fundamental difference between SWT and RAP for compound widgets. Everything that is said about compound widgets in [1] also applies to RAP. If you want to make your compound widget visually distinct, use a custom variants to style the Composite and its children.

Self-drawing widgets

These are also simple in design. Sometimes you might want a widget that completely draws itself. This can be done by extending Canvas. The canvas widget supports drawing in a paint listener. For writing this kind of widgets, you can also follow [1]. Please note that the drawing capabilities of RAP are limited compared to SWT. Especially in Internet Explorer 7 and 8, the performance degrades with the number of drawing operations.

If performance becomes an issue and your custom widgets has layers or areas that need to be redrawn considerably less often than others, you should consider combining this with the compound approach. Using multiple canvas widgets (stacked or in any layout), you can reduce the number of operations by just painting on the canvases that need to be updated. Note that modern browser draw very fast, so the impact of this strategy is much less noticeable than with older ones like Internet Explorer 7. (Though you also safe some traffic.)

Browser-based widgets

Overview

These can still be rather simple. The SWT Browser widget lets you place any HTML into your application. In RAP, this is no different. Any HTML document with JavaScript placed in a Browser widget will end up in an IFrame element. This makes it easy to wrap Web 2.0 applications. Those "mashups" may also be based on Flash or any other browser technologies, or include existing components from other JavaScript libraries. You can call JavaScript from Java by using evaluate, and vice versa with the BrowserFunction class. The drawback is that this kind of client-server communication is considerably less efficient that the RAP-internal Ajax architecture. (Requests may be more frequent and block the UI because they are synchronous.)

General Hints

When using the JEE compatibility OperationMode, the Browser evaluate method works differently. Read about it here and here. If your custom widget is supposed to implement getter that needs to obtain a value using evaluate, do not use the JEE compatibility mode.

Remember not to subclass Browser but extend Composite instead and wrap the Browser widget. This way, you do not expose the API of the Browser to the user of your widget, but instead provide an API that is specific for your widget. It's recommended to always use evaluate instead of executeScript. Before you can use evaluate, you must wait until the document is fully loaded, using either a ProgressListener or a BrowserFunction.

Each call to a BrowserFunction or to evaluate creates an HTTP request. To reduce the resulting traffic you can try combining sequential calls. A single call can transport as many information as you wish: evaluate has no limit on the number of executed JavaScript-functions. BrowserFunctions take any number of arguments and can return several values using an array of Object.

How to load required resources

It's important to decide how your resources (HTML JavaScript, CSS and image files) are provided to the browser widget. If you use only a moderate amount of HTML with inlined JavaScript and CSS (and no images), or most of your resources can be loaded from a different HTTP-server, it will suffice to use the setText method of the browser widget. The resulting custom widget will also run in an SWT application. However, when using setText the Browser can not cache the loaded document, so each new instance has to load and parse it again. A good example of a “mashup” custom widget using this strategy is the Browser-based Google Maps widget. [3]

When a not all resources can be inlined in the HTML file (like images), and they are to be provided by the RAP application itself, there are multiple other options. However, the resulting custom widget will not work in an SWT application.

ClientScripting-enhanced widgets

ClientScripting is a RAP Incubator component that allows adding client-side behavior to existing RAP widgets. When your custom-widget can graphically be represented by one or more existing SWT/RAP-widgets, but cannot be reasonably well implemented as a compound widget because of the latency of the HTTP-requests involved, ClientScripting is often the ideal solution. It can also help in some cases where certain SWT events are not implemented in RAP (MouseEnter/MouseExit), or are limited compared to SWT (Verify). ClientScripting is not to be confused with developing a native RAP custom widget. While it partially runs on the client, the difference is that ClientScripting provides an SWT-like API and does not require accessing RAP internals.

ClientScripting is as of June 2012 not yet feature-complete. However, all existing API is stable and bugs can be reported in the RAP Bugzilla. Detailed information can be found in the RAP Wiki [6], including some JavaScript hints and tips for Java Developer.

Native Custom Widgets

Just like in SWT, writing real native custom widgets is hard. You need deep knowledge of both RAP and the platform you are developing for, i.e. the browser and any libraries you use. Also, in contrast to all other types of custom widgets, there is currently no guarantee that a native custom widget developed for one version of RAP will work in any future versions, as its partially based on internal API. This might be improved in RAP 2.0 (Kepler).

We currently recommend to use any of the alternatives above. A native custom widget should only be required if for some reason you need to work directly with HTML/DOM API, and the Browser widget is considered too inefficient for your use case Detailed information for native RAP custom widget development can be found via the RAP Wiki. [7]

External Resources