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