This post is intended to be the next steps towards a TDD approach with GWTP. We’ll try to show you the patterns and workflow of writing a GWTP application in a TDD fashion. Continue reading “Testing patterns in GWTP”
In the previous article, we laid the foundation for our toaster launcher application. We created a Presenter and a View. We saw how to use UiBinder to declare HTML elements using XML markup. We also used UiHandlers to delegate View events to the Presenter.
In this post, we will continue to build upon that foundation, and start our toaster’s incredible journey into space.
This tutorial will go over the following features:
- Gatekeeper: Protecting your assets
- PlaceManager: Going from one place to another
- PresenterWidget: Reusable controls with their own logic
- RestDispatch: Communicating the RESTful way
This is an overview of the structure that the application will have by the end of this tutorial.
A Gatekeeper is used to protect a Presenter from unauthorized access. The Gatekeeper can be used to prevent revealing unauthorized sections of the application – a login page or an administration section, for example. When a Presenter is protected by a Gatekeeper, the
canReveal() method is called before the Presenter is revealed. If the method returns true, the Presenter will be revealed, otherwise it will not. For instance, this method can be used to verify if a user is logged in.
@DefaultGatekeeper annotation specifies that every Presenter which has a ProxyPlace will be using this Gatekeeper. But what if you don’t want to use the default Gatekeeper on a specific Presenter? The
@NoGatekeeper annotation takes care of that. We’re going to use this annotation in the next example.
Creating the login page
To prevent anyone from accessing the application without authorization, we’re going to create a login page. Now that we know how to create a Presenter, we’re going to create the LoginPresenter:
Here we used
MyProxy interface. We did it to allow the LoginPresenter to always be revealed so that users can enter their credentials. We also stored the user credentials in the Presenter for simplicity. However, this is not recommended in a real life situation. Sensitive information stored on the client-side is not secure. [You’ve been warned 😉 ] We also added a simple validation method for the username and password.
Next, we’re going to create the LoginView and its LoginView.ui.xml twin. I always prefer to create the XML markup first.
By now, if you remember the first tutorial, you should have created LoginUiHandlers and a LoginModule. Don’t forget to install the LoginModule into the ApplicationModule.
Pointing to the login page
Right now the home page of the application points towards the LauncherPresenter. We need to change this because we want the home page to be the LoginPresenter. We can do this by changing the NameToken associated to the default place in the ClientModule.
PlaceManager: Going from one place to another
The PlaceManager allows you to navigate between places in your application. We’re going to use it to navigate to the LauncherPresenter. To do this, we need to inject PlaceManager into the LoginPresenter. Then, all we need to do is to build a PlaceRequest using the
That’s it! After the credentials are validated, the PlaceManager will reveal the LauncherPresenter. The LoggedInGatekeeper’s
canReveal() method will return true and allow the LauncherPresenter to reveal itself.
PresenterWidget: Reusable controls with their own logic
As often happens in a application, you will want to reuse certain UI components – a menu or a form, for example. By using a PresenterWidget for your UI component, you can inject it into any other Presenters.
Creating the PresenterWidget
We’re going to create a PresenterWidget to fetch information about our toaster when it’s out into space.
As you can see, ToasterPresenterWidget extends PresenterWidget rather than Presenter. It also doesn’t have the
MyProxy interface you’d declare in a regular Presenter. Associating a View to a PresenterWidget is done the same way as regular Presenter. So we are going to skip this part. You can always look at the github repository if you want to see exactly how we did it.
Setting the PresenterWidget in a Slot
PresenterWidgets need to be set in a Slot which serves as a placeholder for them. Theses slots are defined in a Parent Presenter. Look at the documentation for the right type of slot to use in your application. In this case, we’re using the regular Slot which is the most permissive. To set the PresenterWidget into the slot, we use the
Binding the Slot to a container
The next step is to bind the slot to a container in which the PresenterWidget will be displayed. This is done on the Parent View. When the container is defined, it can be bound to the Presenter’s Slot using the
The next time you access the LauncherPresenter, you’ll see the ToasterWidgetPresenter set into it.
RestDispatch: Communicating the RESTful way
REST is everywhere nowadays and GWTP has a client library to communicate with a server in a RESTful way. RestDispatch can be used without GWTP which makes it great for any GWT application. Before you can send data over the wire, your object must be serializable. RestDispatch uses Jackson to serialize to JSON. Because if this, you have to either use
@JsonCreator on your constructor or use a no argument one. For this tutorial, we’re going to use the no argument constructor. We also assume that you have read the documentation on how to add RestDispatch to your pom.xml and make your GWT module inherit from it.
We are going to use RestDispatch to make requests to the external API. The first request we’re going to make is for the toaster launch. It will send a POST request to the API with the coordinates and power parameters. The second is a GET request that will retrieve information about the toaster.
Creating a resource
Let’s start by creating a ToasterResource for RestDispatch to use.
RestAction<R> will take care of deserializing the response and returning an object.
The next step is to create a Gin Module to install the RestDispatchAsyncModule and bind the RestApplicationPath to the server API endpoint. This module will also need to be installed into the ClientModule.
To execute a request, we need to inject RestDispatch and ToasterResource into the Presenter. Then we call the
execute() method to send the request.
This is the launch request from the LauncherPresenter:
And finally, here’s the getToaster request from the ToasterWidgetPresenter:
The Brave Little Toaster can now fly freely out to deep space, and surely you can too start your own GWTP adventure. I hope that what you learned in this tutorial will help you in your future GWT applications. Feel free to comment on this post or on content that you might like to see in a future post.
Subscribe to our newsletter to be notified when the next post comes out!
This tutorial is intended for people that are new to GWT/GWTP and wish to get started quickly. It will be heavily inspired on the ArcBees developer’s website tutorial which is much more detailed. This is meant to be a brief overview on how to build a basic application with GWT/GWTP. You won’t be able to send your toaster into space after this tutorial, but it will be close enough…
To get started, I strongly suggest watching our how-to video on how to create a basic project. This will create a basic “Hello World!” application for you generated from our Maven Archetypes. You can also use our GWTP plugin for IntelliJ or GWTP plugin for Eclipse if you wish to generate the files yourself.
From the generated application, we’re going to delete the
home package because we’re going to replace it with our own, created from scratch. So this is what the application structure will look like:
+- application/ | \- launcher/ | +- LauncherModule.java | +- LauncherPresenter.java | +- LauncherUiHandlers.ui.xml | \- LauncherView.java | +- ApplicationModule.java | +- ApplicationPresenter.java | +- ApplicationUiHandlers.java | +- ApplicationView.java | \- ApplicationView.ui.xml +- gin/ | \- ClientModule.java +- place/ \- NameTokens.java
The Controls: Writing the View
From the basic archetype, we’re going to create what we need in order to send our toaster into space.
In GWTP, there’s this concept of Presenter-View pair. If you’re not familiar with these terms, it refers to the MVP architecture. The Presenter is where all of the client-side logic should be written (i.e. validation, manipulation to the model layer, etc). The View only displays what the Presenter tells it to display, and should not contain any logic. It takes care of browser-specific events and is the only layer aware of DOM elements. To create our form, we won’t need a Presenter just yet, but we do need a View.
First let’s create a new package under
client/application/launcher. In this package we’ll create a class named
LauncherView. From this View, we will create some fields that will hold the toaster launch parameters.
As you might have guessed, the View implements
LauncherPresenter.MyView which does not exist yet. We will get to that shortly. But first, we need to talk about UiBinder.
UiBinder allows you to declare your HTML and GWT Widgets in XML format. So a View that uses a UiBinder will actually be composed of 2 files, a Java file containing your View class and a XML file containing your HTML.
Now all you have to do is to declare an interface extending UiBinder, like we did in the example above, and create a new XML file named after the View. So in this case, we’ll create
This is the basic skeleton of a UiBinder XML file:
From this node, you will declare all of your HTML elements and/or your GWT Widgets.
On the first line,
xmlns:g='urn:import:com.google.gwt.user.client.ui' are library imports. This means that we’ll use the default GWT widgets for this project, but it also means that you can create your own.
Let’s declare some fields to handle the toaster launch parameters:
ui:field="someName" attribute is how you identify your widgets so you can retrieve them later in your View.
First, we need to declare the variables that will be associated with your widgets.
Now that we have access to the widgets values, we need a way to send them to the
LauncherPresenter so that it can process them. However, in order to do that we also need a way to detect click events on the
In GWTP, UiHandlers are great for delegating some View Events to the Presenter, and that’s hoe we’re going to use them here. We need a new interface that will extend
Now, we’ll be able to bind the
onLaunch() method to a ClickEvent using the
@UiHandler("someIdentifier") annotation. To specify which type of event to listen to, we simply pass the event type as a method parameter.
To send the data to the Presenter we first need to tell the View to use the
LauncherUiHandlers. We do this by extending
ViewWithUiHandlers and this will give us access to
The Logic: Writing the Presenter
Now that we have a LauncherView with some basic controls and a UiHandler to delegate event handling to the Presenter, we can write the LauncherPresenter to handle logic.
In order for the LauncherPresenter to use LauncherUiHandlers, we need to do the following:
- Implement LauncherUiHandlers for the LauncherPresenter
- Extend MyView interface with
- Set the UiHandler for the View:
Then we’ll need to implement the
Now we’re going to add validation so we’re sure wrong values will not turn our toaster into a flaming pile of dust.
In the next post of this tutorial, we’ll learn about how the toaster processes values using RestDispatch. We’ll also protect the LauncherPresenter with a Gatekeeper. The user will need to login before he can access the LauncherPresenter. For this, we’ll create a LoginPresenter using a PresenterWidget.
You can find the second part here.
Last week, we organized our first hackathon ever. It was two days of real fun, focusing on the core of our business : our open source projects.
To help make it even more fun, we assigned team different colors. Each one could win points and leaders could “punish” other teams (mostly making bottom teams serve Mr. Freezes and beer to the other teams ;-)).
The two main focus of the developers were to release the 1.5 version of GWTP (which has been in the making for a few weeks) and to solidify and update the IntelliJ plugin.
Mission Accomplished! It’s time to unveil the latest creations from our team at Arcbees and our many external contributors.
One feature of this release is simplified boilerplate for nested presenters. We don’t need the @ContentSlot annotation anymore. It is now replaced by a NestedSlot type. The @ContentSlot still works but is now deprecated. You can read more about this new slot mechanism on our developer portal.
We also added name token configuration to the DefaultModule builder. As always, we also improved our Rest-Dispatch to be even more useful to our users.
For those of you that were using the IntelliJ plugin, there was a nasty bug that prevented the user from creating a project with the newest archetype and the newest version of IntelliJ. So, it was the first thing we worked on during the first day of the hackathon.
Next, we improved the user experience of the Create Presenter dialog to make it simpler and to make it more clear to describe what is going on.
You can download the last version on the JetBrains plugin repository.
Also, if you prefer to use Maven alone, we just released a short video on how to start a new GWTP project (french version here). Fundamentally, it is the same process the plugin uses when creating a new project : executing the Maven instruction to generate the archetype from a Sonatype repository.
As you can see, the goal of this release is to simplify your GWTP experience as much as possible.
Thanks for your invaluable feedback. It helps us create products that are relevant in real use cases and that immensely simplify a developer’s daily work.
If you’re curious about where we are going with the next major version of GWTP, you can watch this presentation that Christian Goudreau gave at the last GWT.create. He was talking about how to improve your productivity with GWTP, but he gives a glimpse at the end of the talk about what lies ahead for GWTP.
Stay tuned for more to come and feel free to let me know how we can help you become more efficient with this framework.
When looking for a framework to build our codebase on, we came across GWT. Although we didn’t have any prior experience with GWT, we were a team of seasoned Java devs, so it seemed a natural fit for our skillset. Plus it offered the client-side UI building approach we still believed in. Still, a lot of base work was required to build out the basic infrastructure of our application. This is where the GWTP framework came in handy. It made our introduction to GWT much easier and gave us a headstart in development.
One of the major problems of our vanilla JS solution was that we had to take care of every single piece of application and UI logic ourselves. And, because Ruxit is a single-page application, there was a lot of logic to be tracked. GWTP provides lots of helpful boilerplate functionality like view lifecycles and connecting URLs to corresponding views. GWT is a great technology with a learning curve that’s not too steep. However it does take some time to adjust your mindset to the work approach that’s required for succeeding with GWTP.
As mentioned, GWTP made our start with GWT much easier but at the same time the framework it provides is not restrictive. Yet it covers most of the basics that are needed to successfully get your application up and running. Over the time that we’ve worked with GWTP—which is three years at this point—we’ve never felt that GWTP has constrained us, which is phenomenal. We’re convinced that it’s the balance between structure and freedom that makes GWTP so appealing.
One of our favorite features in GWTP is code-splitting. Sure, code-splitting is included with GWT, but you have to take special care to set the split points right. If you don’t get the split-points right from the beginning, it can be really hard (if not impossible) to introduce them later as the code is usually too tightly bound by then. GWTP’s Model-View-Presenter architecture offers an easy and efficient solution to this problem. By applying MVP, your code automatically comes in the right granularity for code-splitting. Without it, we would likely be in a very bad situation at this point, needing tens of megabytes of UI code to be loaded into the browser right from the start. Instead, when opening a Ruxit view for the first time, only the code required to render the current view is downloaded.
With GWTP your code is typically loosely coupled. The advantage to this becomes apparent once your team and code grow in size. Today we’re about three years into development with GWTP and we’ve grown into six teams spread across three countries with almost 230,000 lines of code checked into our repository. Thanks to GWTP our teams don’t step on each other’s toes; each team only runs the views that are relevant to their work. This makes GWT development much faster and less error-prone.
As we had a considerable amount of backend code running from the vanilla JS version we developed early on, we didn’t want to revise all of it just to match our new GWT frontend. That’s why we decided to stay with JSON for communication between our frontend and backend. With this approach, we were able to re-use nearly 100% of our backend functionality without losing anything. The web really is a great place to be a dev. 🙂
We believe that seeing is believing. So, want to see what can be achieved with GWT and GWTP? Have a look at the screenshots of Ruxit below, or better yet, sign up for a free trial of Ruxit.
We’re very proud of our results with GWTP. Having started several additional projects since then, no one was looking for a new development alternative when a new project came around.
Subscribe to our newsletter to be notified when the next post comes out!
Not too long ago, I started using GWT and GWTP and found it pretty hard to understand its event system.
I still can’t find much recent information about it, so I am writing this post to hopefully help others. Disclaimer: There many ways to achieve what I do in this post, but this is the way I prefer.
All right! Let’s demonstrate how events and the event bus work by creating a CSI-Hacking Dashboard. You can get the code on GitHub.
HackerPresenter and a root Presenter that holds/creates other widgets. We also have a
ComputerHackedHandler. The event will be raised to signal that the computers got hacked, and the handler code will be executed after that.
Here’s the classic implementation of a GWT event. Our event will only carry the hacker’s name.
I usually declare my handler as a nested interface in the event declaration. That’s only a matter of personal preference though.
Next we have to raise the event. That will be done by our
HackerPresenter. A really simple way of becoming a computer hacker, is by adding a button to the screen and pressing it, right CSI?
Here’s the code of the view and the presenter.
So we have a button, and when we click on it, it raises an event. There are a couple of ways to raise an event, but the one I usually use, is the static
fire() method on the event. (I’ll talk about the other ways of firing an event later on.)
Now we have to handle the event somewhere. We want to know when the computers get hacked, so we’ll represent the computers with the
ComputerPresenter. Its role will be to print in the console when it gets hacked, and by which hacker. Here’s the presenter code:
This way, when a hacker clicks on the “start hacking” button, all the computers that are listening to the event will print something. As you can see, the
ComputerPresenter registers itself as a handler for the
ComputerHackedEvent through the
This is a convenience method provided by GWTP. Using this method instead of registering directly on the EventBus will make the event registration part of GWTP’s lifecycle and unbind the event handler when the presenter is unbound. That means that if the presenter is unbound and rebound, you’ll have to re-register event handlers. This is why the onBind method is a good place to register handlers.
Here’s the code of the root presenter:
We just create one hacker named Zer0C00L and 2 computers to hack. And now the view:
I got hacked. (A) by Zer0C00L I got hacked. (B) by Zer0C00L
I should start writing in l33tsp33k now.
Now what if you remove one of the ComputerWidgets from the DOM by calling
removeFromSlot(SLOT_COMPUTERS, computerB); and still try to hack the planet?
If you read the output of the console you will see:
I got hacked. (A) by Zer0C00L I got hacked. (B) by Zer0C00L
Wait… What? The handler for the computer B is still registered, the presenter wasn’t unbound, it was only removed from the DOM.
What if we want computer B to stop listening to the events when it’s not present in the DOM? Well that’s a job for
addVisibleHandler. So instead of registering the handler using
addRegisteredHandler we’ll use
addVisibleHandler that will handle this for us. This way, when a presenter is considered “not visible” in GWTP’s lifecycle perspective (read: not visible as in “visible in the DOM”), the event will not reach the handler. The new output should now be:
I got hacked. (A) by Zer0C00L
There’s still a problem though. What if there were too many computers for a single hacker? I think at some point we’ll have to add someone to the team. Let’s do it!
You should see 2 buttons saying “Hack the planet!” and when you click them both, the output is:
I got hacked. (A) by Zer0C00L I got hacked. (B) by Zer0C00L I got hacked. (A) by AcidBurn I got hacked. (B) by AcidBurn
All computers are reacting to every hacker, which is not what we want. This is happening because of the way we registered the handlers earlier. What we want is for the computers to react a specific hacker’s
Since we can have a reference to the said hacker, that is pretty easy to accomplish. We have to delegate the handler registration to the concerned presenter. From the
RootPresenter we’ll delegate the task, but first let’s create an interface :
We can then let
ComputerPresenter implement it.
Note that instead of
registerHandler() you can also use
And finally, when you click on both buttons, the output should be:
I got hacked. (A) by Zer0C00L I got hacked. (B) by AcidBurn
All right! We’re ready to hack the planet! Are we?
Remember when I said I would talk about the ways of firing events? If you are new to GWT and GWTP, you might have noticed that there are multiple methods available to fire events and register handlers.
Confused yet? I can say I was after seeing this. If you dig down you can see that a presenter widget gets an event bus injected and delegates most of its job to it. The only difference is that GWTP manages the handler registrations with its lifecycle (i.e: when a presenter gets unbound, the registered handlers get cleared). Also, if you dig for the
fireEvent method, you’ll see GWTP delegates to
eventBus.fireEventFromSource(). You may want to call the original
fireEvent() if you want to match the following case (taken from the javadoc) “Fires the event from no source. Only unfiltered handlers will receive it”. Honestly, I’ve never faced that situation.
Here’s my cheat sheet of events in GWTP:
– Do I need to fire an event globally on the event bus? (i.e: everything registered to the event will handle it)
N: Go next
– Do I need to filter the handlers by the visibility of the handler?
N: Go next
– Do I need specific handlers to handle events from a specific source?
Y: Create an interface called
HasXXXHandlers and make your handling presenter implement it. GWTP gives
PresenterWidget the capability to register handlers via
registerVisibleHandler(). Finally, fire the event with
N: That’s it. I usually don’t need more options, so the decision tree ends here. If you have another situation that doesn’t fit, let me know!
Arcbees is proud to officially support g(wt)-Query (gQuery), a jQuery-clone API written in Java for GWT. We hope this will helps gQuery grow even further, promoting clear direction and a strong future for this awesome product – one that we ourselves are using in all our projects.
We are firmly committed to keeping gQuery an Open Source product, available under the Apache 2.0. licence. The gQuery project continues to be led by the top three contributors to the codebase: Ray Cromwell, Manuel Carrasco Moñino and Julien Dramaix.
What does our official support of gQuery mean to you? First, gQuery will be part of ArcBees’ other Open Source product offerings, and gQuery support will be included in the support package offered by Arcbees for GWTP. Also, Arcbees is planning a complete re-write of the documentation. This new documentation will follow Arcbees new conventions and will be hosted on github.io.
There is more. This is just the tip of the iceberg! The Arcbees development ecosystem is evolving fast, and you can hear all about it at GWT.create this year!
Le futur de gQuery est assuré!
Arcbees peut se targuer d’être la 1ère entreprise à supporter officiellement g(wt)Query, une librairie similaire à jQuery, mais pour GWT. Fort de cet appui, nous espérons que le produit va continuer de croître en plus d’en assurer sa pérennité, surtout que nous en sommes nous-mêmes de fiers utilisateurs!
Essentiellement, gQuery va demeurer le même produit Open Source offert sous licence Apache 2.0. que vous avez toujours connu et son développement va continuer d’être mené par ses top contributeurs, soit messieurs Manuel Carrasco Moñino, Ray Cromwell et Julien Dramaix.
Vous l’avez peut-être déjà constaté, mais les sources ont été transférées sous Arcbees (github) et d’importants changements se pointent à l’horizon puisque la ré-écriture complète de la documentation est en cours et que gQuery s’ajoute à la gamme de produits Open Source déjà offerte par Arcbees, faisant en sorte qu’il sera désormais couvert par le forfait de support pour GWTP.
Plusieurs autres modifications sont à venir et vous pourrez en apprendre bien davantage sur le sujet et sur Arcbees lors du prochain GWT.create et lors du dévoilement de notre nouvelle image qui approche à grands pas!