|
Tutorial_ExportingGwtLibrariesToJavascript_es
Exportando librerias desarrolladas en GWT a javascript.
IntroducciónHay numerosas ventajas en usar GWT para desarrollar código javascript de calidad, especialmente que el programador no tiene que ser un experto en javascript, conocer particularidades de cada navegador, empaquetamiento de javascript, ofuscación, dependencias entre librerías, etc. Comparando, la relación que existe entre GWT y javascript, es la misma que entre el lenguaje C y código ensamblador. ¿Para qué voy a programar en un lenguaje de bajo nivel con características distintas para cada plataforma si se puede trabajar en un lenguaje de alto nivel, y dejar al compilador que corrija errores, compile, enlace, optimice, ofusque, y genere el código mas apropiado para cada plataforma?. Además, al igual que en C se puede usar ensamblador 'inline', en GWT podemos introducir código javascript en nuestro código java utilizando JSNI. Y finalmente, también existen ventajas en publicar tu librería tanto en gwt como en javascript. Principalmente porque así se podrán aprovechar desarrolladores que utilicen otros lenguages y frameworks, y que no conozcan nada de java y gwt. Detalles
package jschismes.client;
public class HelloClass implements EntryPoint{
String prefix = "Hello: ";
public void onModuleLoad() {
// Al cargar la aplicacion, exportamos el metodo
exportHelloMethod(this);
}
// Metodo que queremos usar desde javascript
public String helloMethod(String name) {
return prefix + " " + name;
}
// Solo se usa para crear una referencia a nuestra funcion en el navegador
private native void exportHelloMethod(HelloClass instance) /*-{
$wnd.hello = function(param1, param2) {
return instance.@jschismes.client.HelloClass::helloMethod(Ljava/lang/String;) (name);
};
}-*/;
}Codigo HTML
package jschismes.client;
@Export
public class HelloClass implements Exportable {
String prefix = "Hello: ";
public String helloMethod(String name) {
return prefix + " " + name;
}
}Código HTML
Usando gwt-exporter
package jschismes.client;
@Export
@ExportPackage("jsc")
public class DatePicker extends GWTCDatePickerAbstract implements Exportable {
public void show(){
}
} <script language='javascript'>
var picker = new jsc.DatePicker();
picker.show();
</script>public class GWTCDatePickerAbstract implements Exportable {
@Export("foo")
public void initialise(){
}
} <script language='javascript'>
var picker = new jsc.DatePicker();
picker.show();
picker.foo();
</script>public class JsChismes implements EntryPoint {
public void onModuleLoad() {
GWT.create(DatePicker.class);
}
}public class JsChismes implements EntryPoint {
public void onModuleLoad() {
ExporterUtil.exportAll();
}
}public class JsChismes implements EntryPoint {
public void onModuleLoad() {
onLoadImpl();
}
private native void onLoadImpl() /*-{
if ($wnd.jscOnLoad && typeof $wnd.jscOnLoad == 'function') $wnd.jscOnLoad();
}-*/;
} <script language='javascript'>
function jscOnLoad() {
var picker = new jsc.DatePicker();
picker.show();
}
</script>@Export
public class DatePicker extends GWTCDatePickerAbstract implements Exportable {
public String show(boolean a1, char a2, int a3, long a4, double a5, myClass a6){
}
}@Export
public class myClass implements Exportable {
}@Export
@ExportPackage("jsc")
@ExportClosure
public interface JsClosure extends Exportable {
public void execute(String par1, String par2);
}@Export
@ExportPackage("jsc")
public class DatePicker implements Exportable {
public executeJsClosure(JsClosure closure){
closure.execute("Hello", "Friend");
} <script language='javascript'>
var picker = new jsc.DatePicker();
picker.executeJsClosure(function(arg1, arg2) {
alert(arg1 + "," + arg2);
});
</script>@Export
@ExportPackage("jsc")
public class DatePicker implements Exportable {
Date currentDate = new Date();
public JavaScriptObject getCurrentDate(){
return timeToJsObject(currentDate.getTime());
}
public void setCurrentDate(JavaScriptObject date){
currentDate = new Date(jsObjectToTime(date));
}
private static native JavaScriptObject timeToJsObject(double time) /*-{
return new Date(time);
}-*/;
private static native double jsObjectToTime(JavaScriptObject d) /*-{
return (d && d.getTime) ? d.getTime(): 0;
}-*/;
} <script language='javascript'>
var picker = new jsc.DatePicker();
picker.setCurrentDate(new Date());
alert(picker.getCurrentDate());
</script>@Export
@ExportPackage("jsc")
public class DatePicker implements Exportable {
String caption = "Select a day";
int type = 0;
public DatePicker(JavaScriptObject prop) {
JsProperties jsProp = new JsProperties(prop);
this.type = jsProp.getInt("type");
this.caption = jsProp.get("caption");
});
} <script language='javascript'>
var picker = new jsc.DatePicker({
type: 1,
caption: "Seleccione fecha"
});
</script>public class JsProperties {
JavaScriptObject prop = null;
JsProperties(JavaScriptObject properties) {
this.prop = properties;
}
public String get(String name) {
return getImpl(this.prop, name, "");
}
public int getInt(String name) {
String val = get(name);
return val == null ? null : Integer.valueOf(val);
}
private static native String getImpl(JavaScriptObject p, String name) /*-{
return p[name] ? p[name].toString() : p[name] === false ? "false" : null;
}-*/;
}Configuración del módulo GWTEs conveniente generar un nuevo módulo para exportar nuestra librería. De hecho es mejor no modificar nuestra librería original gwt sino usarla en nuestro nuevo módulo, de esta manera la libreria gwt publicada no dependerá de gwt-exporter. Los pasos para hacer esto son:
<module> <inherits name="com.google.code.p.gwtchismes.GWTChismes"/> <inherits name="org.timepedia.exporter.Exporter"/> <set-property name="export" value="yes"/> </module> @Export
public class Alert extends GWTCAlert implements Exportable {
private JsProperties jsProp;
public Alert(JavaScriptObject prop) {
super();
this.jsProp = new JsProperties(prop);
if (jsProp.defined("className"))
super.setStyleName(jsProp.get("className"));
}
public void show(int seconds) {
super.show(seconds);
}
public void alert(String msg) {
super.alert(msg);
}
public void hide() {
super.hide();
}
}<module> [...] <entry-point class="jschismes.client.JsChismes"/> </module> public class JsChismes implements EntryPoint {
public void onModuleLoad() {
((Exporter) GWT.create(Alert.class)).export();
onLoadImpl();
}
private native void onLoadImpl() /*-{
if ($wnd.jscOnLoad && typeof $wnd.jscOnLoad == 'function') $wnd.jscOnLoad();
}-*/;
<module> [...] <add-linker name="xs"/> </module> Nota: las versiones 1.6.x y 1.7.0 de momento no soportan el 'linker xs' en modo 'hosted', por lo que tendreis que comentar esta linea cuando useis este modo, o crear otro fichero gwt.xml para desarrollo. Documentión de la librería javascriptA diferencia de java, donde es fácil adivinar qué clases, métodos y argumentos usar al utilizar una libreria en un IDE, en javascript es necesario tener una pequeña documentación que nos indique su uso. Dicho esto, no olvides crear y mantener la documentación de tu librería javascript. Desafortunadamente, no hay existía ninguna utilidad para generar documentación automáticamente, por lo que yo creé mis propias convenciones para anotar el código java. Yo utilizo un perl script casero para extraer esta documentación. En las últimas versiones hay una clase que es capaz de producir paginas html a partir de comentarios javadoc echo un vistazo a este anuncio Referencias y ejemplos
©2009 Manolo Carrasco Moñino |