Google Web Toolkit
Transkrypt
Google Web Toolkit
Google Web Toolkit Piotr Findeisen [email protected] Czym jest GWT kompilator Javy do Javascriptu biblioteki Java/Javascript emulacja części java.lang i java.util „webowe okienka” narzędzia do tworzenia projektów GWT Hosted Web Browser GWT: możliwości kompilatora rozumie Java 2 Standard Edition 1.4.2 i wcześniejsze typy proste: byte, char, short, int, long, float, double, Object, String, T[] Java long → Javascript double try, catch, finally także wyjątki zdefiniowane przez użytkownika bez getStackTrace() także poprzez Java – Javascript RPC Czego kompilator nie umie tak nie można (dodane w J2SE 1.5): for (String c : new String[] {"abc", "def"}) ... ArrayList<Integer> a; Java assert → Javscript no-op brak finalize() brak synchronized, Object.wait(); notify() brak strictfp Java serialization Więcej różnic... wyrażenia regularne podobne, ale nie identyczne używać ostrożnie! brak ładowania klas na życzenie cała logika użytkownika trafia do jednego pliku tylko częściowa implementacja java.lang i java.util więcej o zgodności: http://code.google.com/webtoolkit/documentation/jre.html IDE dla GWT GWT nie jest związane z konkretnym IDE IntelliJ IDEA, Eclipse, NetBeans, JCreator, JBuilder, vim... Eclispe żaden plugin nie jest potrzebny GWT Hosted Mode to com.google.gwt.dev.GWTSHell.main() kiedyś specjalny plugin: Googlipse darmowe narzędzia od Cypal Solutions http://www.cypal.in/studiodocs GWT w Eclipse wygeneruj projekt Eclipse: projectCreator -eclipse MyProject dodaj do niego GWT: applicationCreator -eclipse MyProject com.mycompany.client.MyApplication ... i uruchom ./MyApplication-shell lub zaimportuj projekt do Eclipse Run lub Debug (już zdefiniowane) GWT Hosted Mode Debugowanie w Eclipse Hello World: html Najprostsza strona dołączająca kod GWT src/edu/taw/public/hello.html <html> <head> <script language='javascript' src='edu.taw.Hello.nocache.js'> </script> </head> <body></body> </html> Hello World: moduł gwt.xml src/edu/taw/hello.gwt.xml (istotny do wdrożenia) <module> <!-- Inherit the core Web Toolkit stuff.--> <inherits name='com.google.gwt.user.User'/> <!-- Specify the app entry point class. --> <entry-point class='edu.taw.client.Hello'/> </module> Hello World: Java src/edu/taw/client/Hello.java package edu.taw.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.ui.*; public class Hello implements EntryPoint { } public void onModuleLoad() { Label l = new Label("Strona dynamiczna."); RootPanel.get().add(l); } Hello World: efekt końcowy <html><head> <script src="edu.taw.Hello.nocache.js" language="javascript"> </script> <script> edu_taw_Hello.onInjectionDone('edu.taw.Hello') </script> </head> <body> <iframe src="EC79BAB10271672DBC9D5BC7E9A11901.cache.html" id="edu.taw.Hello" style="border: medium none ; position: absolute; width: 0pt; height: 0pt;"></iframe> <div class="gwt-Label">Strona dynamiczna.</div> </body></html> http://students.mimuw.edu.pl/~findepi/GWT/hello/hello.html JavaScript: nie próbuj tego samemu c=k.getElementById('edu.taw.Hello');var b=c.contentWind function edu_taw_Hello(){var l=window,k=document,t=l.ex function y(){if(ab&&w){var c=k.getElementById('edu.taw. function s(){var j,h='__gwt_marker_edu.taw.Hello',i;k.w ;if(j&&j.src){p=d(j.src);}if(p==''){var c=k.getElements function D(){var f=document.getElementsByTagName('meta' function n(a,b){return b in db[a];} function m(a){var b=z[a];return b==null?null:b;} function cb(d,e){var a=o;for(var b=0,c=d.length-1;b<c;+ function r(d){var e=F[d](),b=db[d];if(e in b){return e; F['user.agent']=function(){var d=navigator.userAgent.to var u;function x(){if(!u){u=true;var a=k.createElement( if(k.addEventListener){k.addEventListener('DOMContentLo edu_taw_Hello.__gwt_initHandlers=function(i,e,j){var d= http://students.mimuw.edu.pl/~pf219427/GWT/hello/edu.taw.Hello.nocache.js http://students.mimuw.edu.pl/~pf219427/GWT/hello/EC79BAB10271672DBC9D5BC7E9A11901.cache.html GWT: dalsze możliwości wiele „żywych” kawałków na jednej stronie brak zależności w kodzie Java czy HTML <module> <!-- Inherit the core Web Toolkit stuff.--> <inherits name='com.google.gwt.user.User'/> <!-- Specify the app entry point class. --> <entry-point class='edu.taw.client.Hello'/> <entry-point class='edu.taw.client.ByeBye'/> </module> GWT a istniejące strony kod GWT może modyfikować tylko wybrany fagment strony (lub nic) package edu.taw.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.ui.*; public class Hello implements EntryPoint { } public void onModuleLoad() { Label l = new Label("Strona dynamiczna."); RootPanel.get("writehere").add(l); } Historia w przeglądarce DHTML ≠ brak historii wystarczy dodać do hello.html kod: <iframe src="javascript:''" id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe> historię kontroluje com.google.gwt.user.client.History historię zmienia com.google.gwt.user.client.ui.Hyperlink (link zmieniający stan aplikacji) JavaScript Native Interface JSNI to „asembler dla Javy” umożliwia zaimplementowanie pojedynczych metod z Javy wprost w JavaScripcie package edu.taw.client; import com.google.gwt.core.client.EntryPoint; public class Hello implements EntryPoint { public native void onModuleLoad() /*-{ $doc.body.innerHTML = "Strona dynamiczna."; }-*/; } kontekst wykonania ImageBundle trywialne w obsłudze umożliwia sklejanie obrazków przyspiesza transfer np. obrazki z googla: http://code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.UserInterface.html#ImageBundles ImageBundle: przykład public interface MyImageBundle extends ImageBundle { /** 'new_file_icon.png', 'new_file_icon.gif', or 'new_file_icon.png' */ public AbstractImagePrototype new_file_icon(); } /** @gwt.resource open_file_icon.gif */ public AbstractImagePrototype openFileIcon(); public class Hello implements EntryPoint { public native void onModuleLoad() { MyImageBundle ib = (MyImageBundle) GWT.create(MyImageBundle.class); RootPanel.get().add( ib.new_file_icon().createImage()); } } internationalization Constants Messages jak Constants, ale całe wyrażenia Dictionary type-safe, definiowane w plikach, statyczne zupełnie dynamiczne nie tylko napisy internationalization Localizable public interface Person extends Localizable { String name(); } public class Person_en implements Person { public String name() { return "John"; } } public class Person_pl implements Person { public String name() { return "Jaś"; } } inlineowane public void localPerson() { Person p = (Person) GWT.create(Person.class); } and more... strona z tą prezentacją: http://students.mimuw.edu.pl/~findepi/GWT/ strona GWT przykłady dokumentacja dostępnych klas bardzo ciekawe prezentacje