GWT Tutorial: Example Application (3)

Once you get here, that means you know how to create a basic GWT application with RPC and Datastore. Now you may want to add access control for your application. What we need here is to build another service. The similar process applied here.

Finally, Class Diagram under client directory.

NoteWatcher.java is the entrypoint. It is listed below, just for general ideas. The complete source code is exported to a zip file. You can download from http://hotfile.com/dl/101385897/0cc8202/NoteWatcher.zip.html. It doesn't inherit previous work in 1 and 2, it is another application.
(The link is dead. Unfortunately I don't have a copy of the code because it was developed very long time ago, before Git became popular. Sorry for the inconvenience, but I don't have time to do it again.)

package com.google.gwt.sample.notewatcher.client;
 
import java.util.ArrayList;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
 
public class NoteWatcher implements EntryPoint {
 
	private VerticalPanel mainPanel = new VerticalPanel();
	private FlexTable notesFlexTable = new FlexTable();
	private HorizontalPanel addPanel = new HorizontalPanel();
	private TextArea newSymbolTextBox = new TextArea();
 
	private Button addNoteButton = new Button("Add");
	private Label lastUpdatedLabel = new Label();
	private ArrayList<String> NotesNames = new ArrayList<String>();
 
	private LoginInfo loginInfo = null;
	private VerticalPanel loginPanel = new VerticalPanel();
	private Label loginLabel = new Label(
			"Please sign in to your Google Account to access the NoteWatcher application.");
	private Anchor signInLink = new Anchor("Sign In");
	private Anchor signOutLink = new Anchor("Sign Out");
 
	// (1) Create the client proxy. Note that although you are creating the
	// service interface properly, you cast the result to the asynchronous
	// version of the interface. The cast is always safe because the
	// generated proxy implements the asynchronous interface automatically.
	private final NoteServiceAsync NoteService = GWT.create(NoteService.class);
 
	/**
	 * Entry point method.
	 */
	public void onModuleLoad() {
		// (1) Check login status using login service.
		LoginServiceAsync loginService = GWT.create(LoginService.class);
		// (2) Create an asynchronous callback to handle the result.
		AsyncCallback acb = new AsyncCallback<LoginInfo>() {
			public void onFailure(Throwable error) {
			}
 
			public void onSuccess(LoginInfo result) {
				loginInfo = result;
				if (loginInfo.isLoggedIn()) {
					loadNoteWatcher();
				} else {
					loadLogin();
				}
			}
		};
		// (3) Make the call. Control flow will continue immediately and later
		// 'callback' will be invoked when the RPC completes.
		loginService.login(GWT.getHostPageBaseURL(), acb);
	}
 
	private void loadLogin() {
		// Assemble login panel.
		signInLink.setHref(loginInfo.getLoginUrl());
		loginPanel.add(loginLabel);
		loginPanel.add(signInLink);
		RootPanel.get("noteList").add(loginPanel);
	}
 
	private void loadNoteWatcher() {
		// Set up sign out hyperlink.
		signOutLink.setHref(loginInfo.getLogoutUrl());
 
		// Create table for Note data.
		notesFlexTable.setText(0, 0, "User");
		notesFlexTable.setCellSpacing(20);
 
		notesFlexTable.setText(0, 1, "Note");
 
		if(loginInfo.getNickname() == "xiaoranlr"){
			notesFlexTable.setText(0, 2, "Remove");
		}
 
		// set button's style
		addNoteButton.addStyleName("addButton");
 
		// Assemble Add Note panel.
		addPanel.add(newSymbolTextBox);
		addPanel.add(addNoteButton);
 
 
		// Assemble Main panel.
		mainPanel.add(signOutLink);
		mainPanel.add(notesFlexTable);
		mainPanel.add(addPanel);
		mainPanel.add(lastUpdatedLabel);
 
		// Associate the Main panel with the HTML host page.
		RootPanel.get("noteList").add(mainPanel);
 
		// Move cursor focus to the input box.
		newSymbolTextBox.setWidth("300px");
		newSymbolTextBox.setFocus(true);
 
 
		// Listen for mouse events on the Add button.
		addNoteButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				addNote();
			}
		});
 
		// Listen for keyboard events in the input box.
		newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					addNote();
				}
			}
		});
 
		loadNotes();
 
	}
 
	/**
	 * Add Note to FlexTable. Executed when the user clicks the addNoteButton or
	 * presses enter in the newSymbolTextBox.
	 */
	private void addNote() {
		final String symbol = newSymbolTextBox.getText().trim();
		newSymbolTextBox.setFocus(true);
		newSymbolTextBox.setText("");
 
		// Don't add the Note if it's already in the table.
		if (NotesNames.contains(symbol))
			return;
 
		// displayNote(symbol);
		addNote(loginInfo.getNickname(), symbol);
	}
 
	private void addNote(final String user, final String symbol) {
		// (2) Create an asynchronous callback to handle the result.
		 AsyncCallback callback  = new AsyncCallback<Void>() {
			public void onFailure(Throwable error) {
				//do something, when fail
			}
 
			public void onSuccess(Void ignore) {
				//when successful, do something, about UI
				displayNote(user, symbol);
			}
		};
 
		// (3) Make the call. Control flow will continue immediately and later
		// 'callback' will be invoked when the RPC completes.
		NoteService.addNote(user, symbol, callback);
 
	}
 
	private void displayNote(final String user, final String symbol) {
		// Add the Note to the table.
		int row = notesFlexTable.getRowCount();
		NotesNames.add(symbol);
 
		notesFlexTable.setText(row, 0, user);
		notesFlexTable.setText(row, 1, symbol);
 
		// Add a button to remove this Note from the table.
		if (loginInfo.getNickname() == "xiaoranlr") {
 
			Button removeNoteButton = new Button("x");
			removeNoteButton.addStyleDependentName("remove");
			removeNoteButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					removeNote(symbol);
				}
			});
			notesFlexTable.setWidget(row, 2, removeNoteButton);
		}
	}
 
	private void removeNote(final String symbol) {
		NoteService.removeNote(symbol, new AsyncCallback<Void>() {
			public void onFailure(Throwable error) {
			}
 
			public void onSuccess(Void ignore) {
				undisplayNote(symbol);
			}
		});
	}
 
	private void undisplayNote(String symbol) {
		int removedIndex = NotesNames.indexOf(symbol);
		NotesNames.remove(removedIndex);
		notesFlexTable.removeRow(removedIndex + 1);
 
	}
 
	private void loadNotes() {
		NoteService.getNotes(new AsyncCallback<String[]>() {
			public void onFailure(Throwable error) {
			}
 
			public void onSuccess(String[] symbols) {
				displayNotes("anonymous", symbols);
			}
		});
 
	}
 
	private void displayNotes(String user, String[] symbols) {
		for (String symbol : symbols) {
			displayNote(user, symbol);
		}
	}
 
}
Category >> Google Web Toolkit  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • don

    have you got the full source code pleaseeeee ?????

  • Michelle

    Very good example. But the source code link is broken. Could you please provide the complete source code? That will be very helpful!
    Thank you!

  • Yashgin

    I want to know if it’s possible to get the complete source code the link of the source code is broken . Thank you.

  • RomuLaGrinta

    Nice work ! I want to know if it’s possible to get the complete source code because the link is dead. Thank you.

  • Christian

    I’ve followed GWT Tuto 2 but I’ve a error message :

    com.google.appengine.tools.development.LocalResourceFileServlet doGet
    WARNING: No file found for: /UDNotes.html

  • admin

    publish to google app engine. it is possible because of data store setup on your local machine.

  • Calvin

    I’ve followed GWT Tutorial Example Application (1) and (2) exactly.

    I can run it as Web application in Eclipse, but when I click on the button “Add” I get the following error: “Failed”.

    So nothing is saved to GAE Datastore.

    How can I fix it?

    Thanks in advance!

  • Admin

    I can not figure out your problem based on those error messages. I suggest you do it step by step instead of using the zipped project.

  • Berkan

    Hi Ryan, I cannot get this zipped project run on my computer. Eclipse gives this error:
    Exception in thread “main” java.lang.NoSuchMethodError: org.mortbay.thread.Timeout.(Ljava/lang/Object;)V
    at org.mortbay.io.nio.SelectorManager$SelectSet.(SelectorManager.java:306)
    at org.mortbay.io.nio.SelectorManager.doStart(SelectorManager.java:223)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
    at org.mortbay.jetty.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:303)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
    at org.mortbay.jetty.Server.doStart(Server.java:233)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
    at com.google.gwt.dev.shell.jetty.JettyLauncher.start(JettyLauncher.java:667)
    at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:500)
    at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1055)
    at com.google.gwt.dev.DevModeBase.run(DevModeBase.java:804)
    at com.google.gwt.dev.DevMode.main(DevMode.java:309)

    I have the lates GWT SDK and the Eclipse plugin.
    Do you have any ideas?
    Thanks a lot.

  • Alessandro

    Ryan, great post. I’m just getting familiar with GWT and I’ll have to develop my app with some of the RPC concepts you’ve wrote about here. I’m unfamiliar with RPC but this page has helped alot. I’ll be integrating BIRT with GWT for the client. Thx for the post.

  • admin

    Hi, Thanks for your message. It sounds good, and I’m interested in the Drag and Drop stuff. But I can’t do that recently. I may do that later.
    Thanks.

  • Martinho

    Hi Ryan. Thanks for your post about GWT.
    I´ll take a detail look later.
    I´m also a student and i´ll have to make a GWT project. It will have to support a database(maybe MySQL) and drag and drop (have some restrictions), it´ll be basically a “Scheduler Timetable Manager” for the school. If you can post something about that i´d be glad. I´ll bookmark your site. Thanks.