Introduction
GWT is a toolkit used to write AJAX applications using java language. It comes with Java to JavaScript compiler and a special browser that helps in debugging the GWT applications. GWT Provides lot of user interface widgets that can be utilized to create new applications.There are two modes of running GWT application. They are: 1.
also read:
- Code Splitting in GWT
- What is Model View Presenter (MVP) in GWT Application?
- Internationalisation(i18n) in GWT Application
Development mode 2.Production mode.
In Development Mode, the application runs java byte code within the JVM.
As it runs within the JVM it takes the advantage of java’s debugging facilities. In Production Mode ,the application run’s as JavaScript and HTML using GWT compiler which converts Java code to JavaScript.
History Class
As most other Ajax based applications, GWT applications also run in a single page. This approach of work creates the problem of Back Button. The problem is if the user needs to go to previous page or next page then the results will be unpredictable. GWT provides a solution for this problem is through the History class.
Browser history keeps track of all the URLs that are loaded. It is a dynamic stack of URLs, where the browser displays the top URL of the stack. History class is used to interact with the browser’s history stack. GWT maintains the browser history as tokens which hold the state of the application mapped to them by the developer. Token is represented as String which should be associated to a given in the program. All the History class methods are static. Some of the methods of them are getToken(), newItem(String), back(), forward() , addValueChangeHandler() and so on.
Sample Application
The sample application we discuss here demonstrates how to add history support to the GWT application. We will create Login application which has the history support. In this application, we will create two views one is Login view and the other one is Welcome view. Let us see the step by step procedure for the same.
Software Requirements
For this Sample application i have used the following software’s.
- JDK 1.6
- Eclipse 3.6 IDE
- GWT SDK 2.1.1
- GWT Eclipse Plug-in
- GWT plug-in for chrome browser. (to run in development mode)
Project Structure
Steps to add History support
-
Setup the HTML page.
- Add the following iframe to the html page(home
page) of the application.
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"> </iframe>
This iframe will be automatically inserted in the html page when creating the Application. This code is required if your application is running in ie6 or ie7 which lack the necessary onhashchange event. This script is not required for Firefox, chrome, safari or ie8 browsers. Ie8 browser supports the onhashchange event so it works on ie8 without this script.
2. Add the valueChangeHandler to the application EntryPoint Class.
The handler will be invoked on every history change event. Below is the code for adding the handler to the application.
public class LoginHistoryDemo implements EntryPoint, ValueChangeHandler { private static final String LOGIN_TOKEN = "login"; private static final String WELCOME_TOKEN = "welcome"; Label nameError = new Label(); Label pwdError = new Label(); final TextBox nameTextbox = new TextBox(); final PasswordTextBox passwordTextbox = new PasswordTextBox(); public void onModuleLoad() { setupHistory(); } private void setupHistory() { History.addValueChangeHandler(this); History.newItem(LOGIN_TOKEN, true); } }
When the first time application gets loaded, there will not be any change event. We need to set the initial token for the first load using
History.newItem(LOGIN_TOKEN,true); Where in the above code LOGIN_TOKEN and WELCOME_TOKEN are two tokens representing two views of our application. The initial view of application is set to LOGIN_TOKEN.
3.Create the two views Login and welcome.
private void loadLoginView() { final Label loginPrompt = new Label("Please Log in"); final Grid grid = new Grid(3, 3); final Label namePrompt = new Label("Name"); final Label passwordPrompt = new Label("Password"); final Button button = new Button("Login"); private void loadLoginView() { final Label loginPrompt = new Label("Please Log in"); final Grid grid = new Grid(3, 3); final Label namePrompt = new Label("Name"); final Label passwordPrompt = new Label("Password"); final Button button = new Button("Login"); button.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if (validateFormInput()) History.newItem(WELCOME_TOKEN); } }); loginPrompt.addStyleName("loginPrompt"); nameTextbox.addStyleName("nameField"); passwordTextbox.addStyleName("passwordField"); grid.setWidget(0, 0, namePrompt); grid.setWidget(0, 1, nameTextbox); grid.setWidget(0, 2, nameError); grid.setWidget(1, 0, passwordPrompt); grid.setWidget(1, 1, passwordTextbox); grid.setWidget(1, 2, pwdError); grid.setWidget(2, 1, button); RootPanel.get().clear(); RootPanel.get().add(loginPrompt); RootPanel.get().add(grid); } private void loadWelcomeView() { final Label welcomeMsg = new Label("Welcome to the GWT History Demo"); welcomeMsg.addStyleName("welcomeMsg"); RootPanel.get().clear(); RootPanel.get().add(welcomeMsg); RootPanel.get().add(new Hyperlink("Logout", LOGIN_TOKEN)); }
Here the username and password fields are validated using the method validateFormInput().
protected boolean validateFormInput() { // validating the username and password fields String name = nameTextbox.getText(); boolean nameIsValid = name.length() > 0; nameError.setText(nameIsValid ? "" : "Please enter the Name"); String pwd = passwordTextbox.getText(); boolean pwdIsValid = pwd.length() > 0; pwdError.setText(pwdIsValid ? "" : "Please enter the Password"); return (name
4. Implement the onValueChangeEvent() method of the ValueChangeHandler
public void onValueChange(ValueChangeEvent event) { String historyToken = event.getValue(); if (LOGIN_TOKEN.equals(historyToken)) { loadLoginView(); } else if (WELCOME_TOKEN.equals(historyToken)) { loadWelcomeView(); } }
On every History change event the appropriate view gets displayed. This changing of views should be written inside the onValueChange() method of the Handler. When the user clicks the Login button, we call History.newItem() but this time we pass the WELCOME_TOKEN token. Once again, GWT invokes our history Handler’s onValueChange method.
Putting it all Together
public class LoginHistoryDemo implements EntryPoint, ValueChangeHandler { private static final String LOGIN_TOKEN = "login"; private static final String WELCOME_TOKEN = "welcome"; Label nameError = new Label(); Label pwdError = new Label(); final TextBox nameTextbox = new TextBox(); final PasswordTextBox passwordTextbox = new PasswordTextBox(); public void onModuleLoad() { setupHistory(); } private void setupHistory() { History.addValueChangeHandler(this); History.newItem(LOGIN_TOKEN, true); } private void loadLoginView() { final Label loginPrompt = new Label("Please Log in"); final Grid grid = new Grid(3, 3); final Label namePrompt = new Label("Name"); final Label passwordPrompt = new Label("Password"); final Button button = new Button("Login"); button.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if (validateFormInput()) History.newItem(WELCOME_TOKEN); } }); loginPrompt.addStyleName("loginPrompt"); nameTextbox.addStyleName("nameField"); passwordTextbox.addStyleName("passwordField"); grid.setWidget(0, 0, namePrompt); grid.setWidget(0, 1, nameTextbox); grid.setWidget(0, 2, nameError); grid.setWidget(1, 0, passwordPrompt); grid.setWidget(1, 1, passwordTextbox); grid.setWidget(1, 2, pwdError); grid.setWidget(2, 1, button); RootPanel.get().clear(); RootPanel.get().add(loginPrompt); RootPanel.get().add(grid); } private void loadWelcomeView() { final Label welcomeMsg = new Label("Welcome to the GWT History Demo"); welcomeMsg.addStyleName("welcomeMsg"); RootPanel.get().clear(); RootPanel.get().add(welcomeMsg); RootPanel.get().add(new Hyperlink("Logout", LOGIN_TOKEN)); } protected boolean validateFormInput() { // validating the password is not empty String name = nameTextbox.getText(); boolean nameIsValid = name.length() > 0; nameError.setText(nameIsValid ? "" : "Please enter the Name"); String pwd = passwordTextbox.getText(); boolean pwdIsValid = pwd.length() > 0; pwdError.setText(pwdIsValid ? "" : "Please enter the Password"); return (nameIsValid && pwdIsValid); } @Override public void onValueChange(ValueChangeEvent event) { String historyToken = event.getValue(); if (LOGIN_TOKEN.equals(historyToken)) { loadLoginView(); } else if (WELCOME_TOKEN.equals(historyToken)) { loadWelcomeView(); } } }
Conclusion
also read:
- Code Splitting in GWT
- What is Model View Presenter (MVP) in GWT Application?
- Internationalisation(i18n) in GWT Application
In this article we learned how to add History support to the GWT application, allowing the user to use the Back and Forward buttons of the browser at will, leading to a general launcher for any application.