Create Eclipse RAP Widget from ClientScripting-based widget
View more Tutorials:
The document was written based on:
-
Eclipse 4.4 (LUNA)
-
Eclipse RAP 2.3
Suppose that you have a Widget written in JavaScript, you want to build a RAP Widget based on above JavaScript widget. It is quite feasible.
Examples LogJS is a widget written in javascript, it includes 2 files logjs.js & logjs.css . Our target is to create a widget on RAP use LogJS.
Examples LogJS is a widget written in javascript, it includes 2 files logjs.js & logjs.css . Our target is to create a widget on RAP use LogJS.

Images of LogJS on html pages.

logjs.js
function LogJS(element) { this.div = document.createElement("div"); this.div.className = 'logjs'; element.appendChild(this.div); this.div.innerHTML = "<p>INFO: Loaded APR based Apache Tomcat Native library 1.1.22.</p>"; this.appendInfo = function(text) { this.div.innerHTML = this.div.innerHTML + "<p class='info'>INFO: "+ text +"</p>"; }; this.appendErr = function(text) { this.div.innerHTML = this.div.innerHTML + "<p class='err'>ERROR: "+ text +"</p>"; }; this.appendWarn = function(text) { this.div.innerHTML = this.div.innerHTML + "<p class='warn'>WARN: "+ text +"</p>"; }; this.clearAll = function() { this.div.innerHTML = ""; }; }
logjs.css
.logjs { width: 100%; height: 100%; margin: 0px; padding: 5px; border: 1px solid #C4C4C4; color: #0AC005; background-color: #111111; font: 13px Verdana, "Lucida Sans", Arial, Helvetica, sans-serif; white-space: nowrap; overflow-y: scroll; overflow-x: scroll; } .logjs p { margin: 0px; padding: 0px; } .logjs .info { } .logjs .err { color: red; } .logjs .warn { color: yellow; }
index.html
<html> <head> <script type="text/javascript" src="logjs.js"></script> <link rel="stylesheet" type="text/css" href="logjs.css" /> </head> <body> <div id="logjs1" style="width: 500px; height: 300px;"></div> <br><br> <button onclick="appendInfo('Starting Servlet Engine: Apache Tomcat/7.0.23')">Add Info Line</button> <button onclick="appendErr('Starting Servlet Engine: Apache Tomcat/7.0.23')">Add Error Line</button> <button onclick="appendWarn('Starting Servlet Engine: Apache Tomcat/7.0.23')">Add Warn Line</button> <script type="text/javascript"> var element = document.getElementById('logjs1'); var logjs = new LogJS(element); function appendErr(text) { logjs.appendErr(text); } function appendWarn(text) { logjs.appendWarn(text); } function appendInfo(text) { logjs.appendInfo(text); } </script> </body> </html>
First we need to create a project to configure the RAP environment .Essentially, it is declarations of the RAP library.
Create a Java project - RAPTarget.

Create file "Target Define"



Add library

Khai báo thư viện RAP
- Name: RAP Runtime 2.3
- Location: http://download.eclipse.org/rt/rap/2.3


Click "Set as Target Platform" for the the RAP library work with every Project in the workspace.

- File/New/Other...

Enter:
- Project Name: LogComposite

Do not select any Template.

Your project has been created:

Declare plugins required for this Plugin:
- org.eclipse.rap.ui
- org.eclipse.equinox.http.registry

You need to create a logjsreources package and copy the javascript files, related style in this package. As shown below below:

Next create 2 javascript file:
- rap-handler.js
- Acting as the intermediary communication between RAP Widget and ClientScripting-based Widget
- load-css-file.js
- this file is in charge of load css files to web pages (specifically here is logjs.css).

load-css-file.js
// var cssId = 'logjs-css-file'; if (!document.getElementById(cssId)) { var head = document.getElementsByTagName('head')[0]; var link = document.createElement('link'); link.id = cssId; link.rel = 'stylesheet'; link.type = 'text/css'; link.href = '/rwt-resources/logjs/logjs.css'; link.media = 'all'; head.appendChild(link); }
rap-handler.js
(function() { 'use strict'; rap.registerTypeHandler("o7planning.LogComposite", { factory : function(properties) { return new o7planning.LogComposite(properties); }, destructor : "destroy", properties : [ "abc" ], events : [], methods : [ 'appendWarn', 'appendErr', 'appendInfo', 'clearAll' ] }); if (!window.o7planning) { window.o7planning = {}; } // Constructor o7planning.LogComposite = function(properties) { bindAll(this, [ "layout", "onReady", "onSend", "onRender", "onChange" ]);// @custom this.parent = rap.getObject(properties.parent); this.element = document.createElement("div"); this.parent.append(this.element); this.parent.addListener("Resize", this.layout); this.logjs = new LogJS(this.element); // Render interface rap.on("render", this.onRender); }; o7planning.LogComposite.prototype = { ready : false, onChange : function() { }, onReady : function() { }, // Render interface in Client onRender : function() { if (this.element.parentNode) { rap.off("render", this.onRender); rap.on("render", this.onRender); rap.on("send", this.onSend); } }, // onSend : function() { }, destroy : function() { rap.off("send", this.onSend); try { this.element.parentNode.removeChild(this.element); } catch (e) { try { console .log('error call this.element.parentNode.removeChild(this.element) :' + e); } catch (e) { } } }, layout : function() { if (this.ready) { var area = this.parent.getClientArea(); this.element.style.left = area[0] + "px"; this.element.style.top = area[1] + "px"; this.editor.resize(area[2], area[3]); } }, setAbc : function(abc) { }, appendErr : function(json) { var text= json["text"]; this.logjs.appendErr(text); }, appendWarn : function(json) { var text= json["text"]; this.logjs.appendWarn(text); }, appendInfo : function(json) { var text= json["text"]; this.logjs.appendInfo(text); }, clearAll : function() { this.logjs.clearAll(); } }; var bind = function(context, method) { return function() { return method.apply(context, arguments); }; }; var bindAll = function(context, methodNames) { for (var i = 0; i < methodNames.length; i++) { var method = context[methodNames[i]]; context[methodNames[i]] = bind(context, method); } }; var async = function(context, func) { window.setTimeout(function() { func.apply(context); }, 0); }; }());
LogComposite is a Widget extends from Composite class and have some method like LogJS
- appendErr
- appendInfo
- appendWarn
- clearAll

LogComposite.java
package org.o7planning.customwidget.logcomposite; import java.io.IOException; import java.io.InputStream; import org.eclipse.rap.json.JsonObject; import org.eclipse.rap.json.JsonValue; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.client.service.JavaScriptLoader; import org.eclipse.rap.rwt.remote.AbstractOperationHandler; import org.eclipse.rap.rwt.remote.Connection; import org.eclipse.rap.rwt.remote.OperationHandler; import org.eclipse.rap.rwt.remote.RemoteObject; import org.eclipse.rap.rwt.service.ResourceManager; import org.eclipse.rap.rwt.widgets.WidgetUtil; import org.eclipse.swt.widgets.Composite; public class LogComposite extends Composite { private static final long serialVersionUID = -8590973451146216709L; private RemoteObject remoteObject; // The directory containing the file js, css. private static final String REAL_RESOURCE_PATH = "logjsresources"; private static final String REGISTER_PATH = "logjs"; private static final String REMOTE_TYPE = "o7planning.LogComposite"; private final String[] FILENAMES = { "logjs.css", "logjs.js" ,"load-css-file.js" , "rap-handler.js" }; private final OperationHandler operationHandler = new AbstractOperationHandler() { private static final long serialVersionUID = -1979566336567602883L; @Override public void handleSet(JsonObject properties) { System.out.println("##### handleSet ..:"); JsonValue textValue = properties.get("text"); if (textValue != null) { // text = textValue.asString(); } } @Override public void handleCall(String method, JsonObject parameters) { System.out.println("##### handleCall ..:" + method); } @Override public void handleNotify(String event, JsonObject properties) { System.out.println("##### handleNotify ..:" + event); if (event.equals("dirty")) { } } }; /** * Create the composite. * * @param parent * @param style */ public LogComposite(Composite parent, int style) { super(parent, style); // Note: Catching error when viewed on WindowBuilder try { registerResources(); loadJavaScript(); Connection connection = RWT.getUISession().getConnection(); remoteObject = connection.createRemoteObject(REMOTE_TYPE); remoteObject.setHandler(operationHandler); // remoteObject.set("parent", WidgetUtil.getId(this)); } catch (Exception e) { e.printStackTrace(); // throw new RuntimeException(e); } } @Override public void dispose() { super.dispose(); // Call destroy() function in rap-handler.js remoteObject.destroy(); } // Load the js files required at Client. private void loadJavaScript() { JavaScriptLoader jsLoader = RWT.getClient().getService( JavaScriptLoader.class); ResourceManager resourceManager = RWT.getResourceManager(); // Load file logjs.js into page jsLoader.require(resourceManager.getLocation(REGISTER_PATH + "/" + "logjs.js")); // Load file load-css-file.js into page jsLoader.require(resourceManager.getLocation(REGISTER_PATH + "/" + "load-css-file.js")); // Load file rap-handler.js into page. jsLoader.require(resourceManager.getLocation(REGISTER_PATH + "/" + "rap-handler.js")); } private void registerResources() throws IOException { ResourceManager resourceManager = RWT.getResourceManager(); for (String fileName : FILENAMES) { // After registering, you can access on your browser: // (http://localhost:port/rwt-resources/logjs/abc.js ) // logjs/abc.js String path = REGISTER_PATH + "/" + fileName; // Check this resource has been registered yet. boolean isRegistered = resourceManager.isRegistered(path); if (!isRegistered) { ClassLoader classLoader = LogComposite.class.getClassLoader(); // Real Path (in src) // logjsresources/abc.js String realPath = REAL_RESOURCE_PATH + "/" + fileName; InputStream inputStream = classLoader .getResourceAsStream(realPath); if (inputStream == null) { throw new IOException("File not found " + realPath); } try { // Register resource resourceManager.register(path, inputStream); } finally { inputStream.close(); } } } } @Override protected void checkSubclass() { } public void appendWarn(String text) { System.out.println("appendWarn"); JsonObject obj= new JsonObject(); obj.add("text", text); this.remoteObject.call("appendWarn", obj); } public void appendErr(String text) { System.out.println("appendErr"); JsonObject obj= new JsonObject(); obj.add("text", text); this.remoteObject.call("appendErr", obj); } public void appendInfo(String text) { System.out.println("appendInfo"); JsonObject obj= new JsonObject(); obj.add("text", text); this.remoteObject.call("appendInfo", obj); } public void clearAll() { System.out.println("clearAll"); this.remoteObject.call("clearAll", new JsonObject()); } }
You need to export the package org.o7planning.customwidget.logcomposite, to allow other plugins can use LogComposite class in this plugin.

You need to create a Project to test LogComposite. Here, I create a basic RAP application.
- File/New/Other...





Registered to use LogComposite plugin

Open BasicEntryPoint class, modified to allow you to design it on WindowBuilder.

@Override protected void createContents(Composite parent) { // Change code, to enable open with WindowBuilder. parent.setLayout(new FillLayout()); Composite main = new Composite(parent, SWT.NONE); }
Right-click on the BasicEntryPoint class and select "Open with / WindowBuilder Editor".






LogComposite is available on Palette, like the other Widget, you can easily drag and drop it into your design interface.


BasicEntryPoint.java
package simplerapapplication; import org.eclipse.rap.rwt.application.AbstractEntryPoint; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.o7planning.customwidget.logcomposite.LogComposite; public class BasicEntryPoint extends AbstractEntryPoint { private LogComposite logComposite; /** * @wbp.parser.entryPoint */ @Override protected void createContents(Composite parent) { parent.setLayout(new FillLayout()); Composite main = new Composite(parent, SWT.NONE); main.setLayout(new GridLayout(1, false)); logComposite = new LogComposite(main, SWT.BORDER); logComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); Composite composite = new Composite(main, SWT.NONE); composite.setLayout(new RowLayout(SWT.HORIZONTAL)); composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Button btnNewButton = new Button(composite, SWT.NONE); btnNewButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { allErrorLine(); } }); btnNewButton.setText("Add Error Line"); Button btnNewButton_1 = new Button(composite, SWT.NONE); btnNewButton_1.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { addWarningLine(); } }); btnNewButton_1.setText("Add Warning Line"); Button btnNewButton_2 = new Button(composite, SWT.NONE); btnNewButton_2.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { clearAll(); } }); btnNewButton_2.setText("Clear ALL"); } private void allErrorLine() { logComposite.appendErr("Starting Servlet Engine: Apache Tomcat/7.0.23"); } private void addWarningLine() { logComposite.appendWarn("Starting Servlet Engine: Apache Tomcat/7.0.23"); } private void clearAll() { logComposite.clearAll(); } }
Running application:
Right-click the "SimpleRAPApplication" project, select:
- Run As/RAP Application

Above error shows that you need RAP runtime configure, before running the application.



The results run on RAP:
