codestory

Erstellen Sie Eclipse RAP Widget aus dem ClientScripting-basierten Widget

  1. Die Vorstellung
  2. ClientScripting-Based Widget
  3. RAPTarget
  4.  Plugin Project - LogComposite erstellen
  5. Test LogComposite

1. Die Vorstellung

Das Dokument wird auf die Quelle ... basiert
  • Eclipse 4.4 (LUNA)

  • Eclipse RAP 2.3

2. ClientScripting-Based Widget

Angenommen, Sie habe ein mit Javascript geschriebenen Widget, Sie möchten ein RAP Widget auf die Basis von dem oben erwähnten Javasript widget bauen. Das ist ganz machbar.

Zum Beispiel: LogJS ist ein Widget, das mit javascript geschrieben wird. Es schließt 2 File logjs.js & logjs.css. Unser Ziel ist die Erstellung eines widget auf RAP mit der Benutzung von LogJS.
Die Image von LogJS auf die Seite html.
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

Zuerst sollen wir ein Projekt erstellen um die Umgebung RAP zu konfigurieren. Auf die Natur ist es die Anmeldung der Bibliothek RAP.
Erstellen Sie ein Java project - RAPTarget.
Create file "Target Define"
Die Bibliotheke einfügen
Melden Sie die Bibliothek RAP an
  • Name: RAP Runtime 2.3
  • Location: http://download.eclipse.org/rt/rap/2.3
Klicken Sie auf "Set as Target Platform" damit die Bibliothek RAP auf alle Projekte in workspace wirkt.

4.  Plugin Project - LogComposite erstellen

  • File/New/Other...
Geben Sie ein
  • Project Name: LogComposite
Keine Vorlage (template) nicht wählen
Ihr Projekt wird erstellt
Melden Sie die erforderlichen Plugin für diesen Plugin an:
  • org.eclipse.rap.ui
  • org.eclipse.equinox.http.registry
Sie sollen eine Package logjsreources erstellen und die File javascript und die betreffenden Stil in dieser Package kopieren. Wie das folgende Beispiel
Zunächst erstellen Sie 2 File javascript:
  • rap-handler.js
    • als die Kommunikationsvermittler zwischen RAP Widget und ClientScripting-based Widget.
  • load-css-file.js
    • Diese File ist zuständig für das Hochladen der File css auf die Website (genau 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 ist ein Widget, das aus die Klasse Composite ausgeweitert wird und die ähnliche Methode wie LogJS hat
  • 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());
   }
}
Sie sollen die Package org.o7planning.customwidget.logcomposite exportiert damit die anderen Plugin die Class LogComposite von diesem Plugin benutzen können

5. Test LogComposite

Sie sollen ein Projekt erstellen um LogComposite zu prüfen. Jetzt erstelle ich eine grundlegende RAP Applikation
  • File/New/Other...
Registrieren Sie die Verwendung von LogComposite plugin
Öffnen Sie die Code von der Klasse BasicEntryPoint, und ändern damit Sie die Interface auf WindowBuilder entwerfen können
    @Override
    protected void createContents(Composite parent) {
        
        // Change code, to enable open with WindowBuilder.
        parent.setLayout(new FillLayout());
        Composite main = new Composite(parent, SWT.NONE);
    }
Klicken Sie die Rechtmaustaste auf die Klasse BasicEntryPoint und wählen Sie "Open with/WindowBuilder Editor".
LogComposite liegt schon auf die Palette, wie die anderen Widget können Sie es in Ihre Interface ziehen and ablegen.
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();
   }

}
Starten Sie die Applikation
Klicken Sie den Rechtmaustaste auf das Projekt "SimpleRAPApplication" und wählen Sie
  • Run As/RAP Application
Der oben Fehler zeigt, dass Sie die RAP Runtime vor dem Starten der Applikation konfigurieren
Das Ergebnis vom Applikation-Starten