# 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.

- Writing a compound widget does not require any JavaScript knowledge.
- Cross-browser compatibility is ensured by RAP.
- The widgets are re-usable in desktop applications with SWT.

### 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.

- Writing a canvas widget does not require any JavaScript knowledge.
- Cross-browser compatibility is ensured by RAP.
- The widgets are re-usable in desktop applications with SWT.

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.)

- Writing a Browser-based widget requires only minor-to-moderate JavaScript knowledge, unless you write the client component from scratch.
- Cross-browser compatibility is ensured by RAP only for the Browser widget itself, but not for the code that is running inside it.
- The widgets are re-usable in desktop applications with SWT when certain conditions apply (see below).

#### 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.

- Make an entire folder available via the `org.eclipse.equinox.http.registry.resources` extension point. This is the most simple way, but requires the `org.eclipse.equinox.http.registry` bundle. To see an example of this, look at the JQuery-Carousel widget for RAP. [4]
- Register each file using either the `org.eclipse.rap.ui.resources` extension point or your `org.eclipse.rwt.application.ApplicationConfiguration`. This only requires the RWT bundle itself, but necessitates creating a Java class implementing `org.eclipse.rwt.resources.IResource` for each resource-file. It may therefore not be suitable for a larger amount of files.
- Accessing `ResourceManager` directly: This has some small overhead, but then requires only one line per registered file. All required code easily fits into your custom-widget class. No other bundles than RWT are required. A good example for this is the CKEditor widget. [5]

### 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.

- Writing ClientScripting-enhanced widgets requires minor-to-moderate JavaScript knowledge, and no knowledge of any other browser technology.
- Cross-browser compatibility is ensured by RAP as long as EcmaScript-standards are followed and no DOM-elements or RAP-internals are accessed.
- The widgets are currently not innately re-usable in desktop applications with SWT. However, some code can be shared between both platforms, and the rest is easily ported.

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).

- Writing a native widget may require moderate-to-advanced knowledge of JavaScript, HTML/DOM, CSS and any other browser-technology you might want to use, in addition to a good knowledge of RAP internals.
- Cross-browser compatibility has to be ensured by the widget-developer.
- Native custom widgets are not re-usable in SWT desktop applications unless an additional SWT-specific version is being developed.

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

- [1] Writing Your Own Widget
- [2] RAP Wiki - Custom Widgets
- [3] The new Google Maps Widget for SWT and RAP
- [4] JQuery carousel widget for RAP
- [5] CKeditor for RAP
- [6] RAP Wiki - ClientScripting
- [7] RAP Wiki - Native Custom Widgets