Create Eclipse RAP Widget from ClientScripting-based widget
2. ClientScripting-Based Widget
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>
3. RAPTarget
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.

4. Create a Plugin Project - LogComposite
- 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.

5. Test LogComposite
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:

Eclipse RAP
- Package and deploy Eclipse RAP application
- Eclipse RAP Tutorial for Beginners - Basic Application
- Install RAP Tools for Eclipse
- Which Platform Should You Choose for Developing Java Desktop Applications?
- Eclipse RAP Tutorial for Beginners - e4 Workbench Application
- Install Eclipse RAP Target Platform
- Eclipse RAP Tutorial for Beginners - Workbench Application (OLD)
- Create Eclipse RAP Widget from ClientScripting-based widget
- Install RAP e4 Tooling for Eclipse
Show More
Eclipse Technology
- How to get the open source Java libraries as OSGi(s)
- Install Tycho for Eclipse
- Java OSGi Tutorial for Beginners
- Create Java OSGi project with Maven and Tycho
- Install WindowBuilder for Eclipse
- Which Platform Should You Choose for Developing Java Desktop Applications?
- Programming Java Desktop Application Using SWT
- Eclipse JFace Tutorial with Examples
- Install e4 Tools Developer Resources for Eclipse
- Package and Deploy Desktop Application SWT/RCP
- Install Eclipse RAP Target Platform
- Install EMF for Eclipse
- Install RAP e4 Tooling for Eclipse
- Create Eclipse RAP Widget from ClientScripting-based widget
- Install GEF for Eclipse
- Eclipse RAP Tutorial for Beginners - Workbench Application (OLD)
- Eclipse RCP 3 Tutorial for Beginners - Workbench Application
- Simple Eclipse RCP 3 Application - View and Editor integration
- Eclipse RCP 4 Tutorial for Beginners - e4 Workbench Application
- Install RAP Tools for Eclipse
- Eclipse RAP Tutorial for Beginners - Basic Application
- Eclipse RAP Tutorial for Beginners - e4 Workbench Application
- Package and deploy Eclipse RAP application
Show More