Everybody knows : Web is the platform of the future. Developing for the browser unfortunately requires us to learn and write JavaScript. Not only that but we also have to integrate the JavaScript client code with the server side, which often runs on the JVM (i.e. is written in Java). So we have to work in two different languages with completely different tools and APIs, and cannot share code between the client and the server.
The Google Web Toolkit (GWT) provides a way to write your client side web application entirely in Java and have it automatically translated to fast and compact JavaScript. It allows you to access all the browser functionality through a statically typed API. You only have to learn and use one language and you can use your code on the client as well as on the server.
The downside : Java is a bad match for the asynchronous programming model required on the browser and generally forces us to write and read a lot of boilerplate code.
In this session you'll see how programming GWT applications with Eclipse Xtend provides the best of both worlds:
Static typing with advanced IDE support meets a powerful and expressive language - right at your finger tips.
5. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
6. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
7. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
8. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
• Browsers have different levels of maturity and compliance
to standards
9. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
• Browsers have different levels of maturity and compliance
to standards
• Programming to the DOM can be tedious
10. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
• Browsers have different levels of maturity and compliance
to standards
• Programming to the DOM can be tedious
• JavaScript
11. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
• Browsers have different levels of maturity and compliance
to standards
• Programming to the DOM can be tedious
• JavaScript
12. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
• Browsers have different levels of maturity and compliance
to standards
• Programming to the DOM can be tedious
• JavaScript
Many projects also require a server side backend
13. Motivation for GWT:
Modern Single Page Applications
Single Page Application
• Works like a client/server application in the browser
Developing for the Browser is a tough task!
• Browsers have different levels of maturity and compliance
to standards
• Programming to the DOM can be tedious
• JavaScript
Many projects also require a server side backend
•Common toolset, code, and language desirable for frontend
and backend
15. GWT for the win!
Abstraction from differences between
16. GWT for the win!
Abstraction from differences between
17. GWT for the win!
Abstraction from differences between
• Client & Server
o Write everything in Java
o Shared code between Client and Server
18. GWT for the win!
Abstraction from differences between
• Client & Server
o Write everything in Java
o Shared code between Client and Server
• Different Browser implementations
o Special JavaScript per browser
o Common Widgets to unify differences
20. Call from client side: Loading Todos
TodoServiceAsync service = GWT.create(TodoService.class);
service.load(name, new AsyncCallback<List<Todo>>() {
@Override
public void onSuccess(List<Todo> result) {
// store and display todos
}
@Override
public void onFailure(Throwable caught) {
GWT.log("Loading todos failed", caught);
}
});
21. Implementation on server side
public class TodoServiceImpl extends RemoteServiceServlet
implements TodoService {
@Override
public List<Todo> load(String name) {
return getMemcacheService().get(name);
}
@Override
public void save(String name, List<Todo> todos) {
getMemcacheService().put(name, todos);
}
}
22. User Interfaces with GWT
Widgets working on all browsers without
touching the DOM
24. Programmatically Composing Widgets:
Displaying a Todo
FlowPanel view = new FlowPanel();
view.setStyleName("view");
...
Label label = new Label();
view.add(label);
Button button = new Button();
button.setStyleName("destroy");
view.add(button);
button.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// remove element from todo list
}
});
25. Any idea how this will look like
when displayed?
31. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
32. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
XML
33. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
XML
needs Java code for dynamic parts
34. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
XML
needs Java code for dynamic parts
code duplication (through binding)
35. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
XML
needs Java code for dynamic parts
code duplication (through binding)
Imperative using Java
36. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
XML
needs Java code for dynamic parts
code duplication (through binding)
Imperative using Java
all in one place
37. The Tragedy of Building UIs
Declarative using XML
structure of code reflects structure of UI (declarative)
XML
needs Java code for dynamic parts
code duplication (through binding)
Imperative using Java
all in one place
hard to read (imperative)
42. Statically Typed like Java
Compiles To Java
Much more concise
Powerful possibilities
43.
44. Clearing Completed Tasks
clearCompletedButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
List<Todo> result = new ArrayList<Todo>();
for (Todo t : getTodos()) {
if (!t.isDone()) {
result.add(t);
}
}
setTodos(result);
}
});
45. Clearing Completed Tasks
clearCompletedButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
List<Todo> result = new ArrayList<Todo>();
for (Todo t : getTodos()) {
if (!t.isDone()) {
result.add(t);
}
}
setTodos(result);
}
});
46. Clearing Completed Tasks
List<Todo> result = new ArrayList<Todo>();
for (Todo t : getTodos()) {
if (!t.isDone()) {
result.add(t);
}
}
setTodos(result);
47. Clearing Completed Tasks
val List<Todo> result = new ArrayList<Todo>();
for (Todo t : getTodos()) {
if (!t.isDone()) {
result.add(t);
}
}
setTodos(result);
48. Clearing Completed Tasks
val List<Todo> result = new ArrayList<Todo>();
for (Todo t : getTodos()) {
if (!t.isDone()) {
result.add(t);
}
}
setTodos(result);
49. Clearing Completed Tasks
val List<Todo> result = new ArrayList<Todo>();
for (Todo t : getTodos()) {
if (!t.isDone()) {
result.add(t);
}
}
setTodos(result);
60. GWT-RPC in Java
1) Server-Side Service Implementation
public class TodoServiceImpl extends RemoteServiceServlet implements TodoService {
public List<Todo> load(final String name) {
return (List<Todo>) getMemcacheService().get(name);
}
public void save(final List<Todo> todos, final String name) {
getMemcacheService().put(name, todos);
}
}
61. GWT-RPC in Java
1) Server-Side Service Implementation
public class TodoServiceImpl extends RemoteServiceServlet implements TodoService {
public List<Todo> load(final String name) {
return (List<Todo>) getMemcacheService().get(name);
}
public void save(final List<Todo> todos, final String name) {
getMemcacheService().put(name, todos);
}
}
2) Server-Side Service Interface
@RemoteServiceRelativePath("todoService")
public interface TodoService extends RemoteService {
public List<Todo> load(final String name);
public void save(final List<Todo> todos, final String name);
}
62. GWT-RPC in Java
1) Server-Side Service Implementation
public class TodoServiceImpl extends RemoteServiceServlet implements TodoService {
public List<Todo> load(final String name) {
return (List<Todo>) getMemcacheService().get(name);
}
public void save(final List<Todo> todos, final String name) {
getMemcacheService().put(name, todos);
}
}
2) Server-Side Service Interface
@RemoteServiceRelativePath("todoService")
public interface TodoService extends RemoteService {
public List<Todo> load(final String name);
public void save(final List<Todo> todos, final String name);
}
3) Client-Side Async-Interface
public interface TodoServiceAsync {
public void load(final String name, final AsyncCallback<List<Todo>> result);
public void save(final List<Todo> todos, final String name,
final AsyncCallback<Void> result);
}
63. GWT-RPC in Xtend
1) Server-Side Service Implementation
@GwtService
class TodoServiceImpl {
override List<Todo> load(String name) {
return memcacheService.get(name) as List<Todo>
}
override void save(List<Todo> todos, String name) {
memcacheService.put(name, todos)
}
}
64. GWT-RPC in Xtend
1) Server-Side Service Implementation
@GwtService
class TodoServiceImpl {
override List<Todo> load(String name) {
return memcacheService.get(name) as List<Todo>
}
override void save(List<Todo> todos, String name) {
memcacheService.put(name, todos)
}
}
@GwtService is a so called “Active Annotation”.
It adds the needed boilerplate during compilation.
71. public class ToDoView extends Composite {
interface ToDoViewUiBinder extends UiBinder<Widget,ToDoView> {
}
private static ToDoViewUiBinder uiBinder =
GWT.create(ToDoViewUiBinder.class);
@UiField
protected SpanElement clearTodosCount;
@UiField
protected SpanElement remainingTodosLabel;
@UiField
protected FlowPanel todoPanel;
Here’s the boilerplate!
@UiField
protected InputElement toggleAll;
@UiField
protected Element remainingTodosCount;
@UiField
protected Button clearCompleted;
@UiField
protected TextBox todoText;
@UiField
protected Element mainSection;
@UiField
protected Element todoStatsContainer;
// ... actual implementation
}
72. Active Annotations Once More
@WithUiBinding
class ToDoView extends Composite {
// ... actual implementation
}
73. Active Annotations Once More
@WithUiBinding
class ToDoView extends Composite {
// ... actual implementation
}
@WithUiBinding looks up the XML and
adds the boilerplate for you.