I'm currently building a GWT login screen and I managed to get a basic version of the login structure working.
I created the following pieces:
An entry point class (actually it was given).
A main application screen composite.
A login-screen composite.
I have the following logic in my entry point method:
MyApplication mainWindow = null;
public void onModuleLoad() {
LoginScreen loginScreen = new LoginScreen() {
#Override
public String onLogin(String username, String password) {
boolean passwordWasOk = rpcCheckUsernamePassword(username,password); // mechanism not important for this question
if (passwordWasOk) {
RootPanel.get().remove(0);
mainWindow = new MyApplication();
// Using root layout panel as main window is a layout type composite
RootLayoutPanel.get().add(mainWindow);
return null;
} else {
return "password was incorrect";
}
}
};
RootPanel.get().add(loginScreen);
}
So, I created a method in the LoginScreen composite that is called when the user clicks the 'Sign-In' button. If the onLogin method fails its validation of the username and password, then a narrative can be returned to the login composite so that it can update the user. The login screen will stay on the screen until the user uses a correct username/password combination.
My question is, is this the correct way to use composites? Where should my login logic ideally reside. Is a better alternative to inject some sort of login handler object in the constructor of the composite or via a setter or is the method I used quite normal?
As I'm planning to write quite a lot of code, I want to get the coding style correct from the outset.
Any feedback is greatly appreciated.
Thanks,
For complex projects you'd want to use the Model-View-Presenter (MVP) design pattern. It allows you to separate the rendering logic (views) from the business logic. To get you started, the official documentation has two articles about it plus there's that presentation by Ray Ryan that started the whole GWT + MVP = <3 haze :) After that I'd recommend browsing through MVP related questions on SO and GWT's Google Group.
Related
I want to create a GWT UI where I basically will have a single HTML page that loads a PanelA object. The user will then do their thing and eventually perform an action that will move them onto another view/screen.
I have simplified my existing views to contain just a single button which moves the user onto the next page etc. for simplicity I only have 2 views to start.
Here is my start up entry point.
public class StockWatcher implements EntryPoint
{
public void onModuleLoad()
{
final RootPanel rootPanel = RootPanel.get();
rootPanel.add( PanelA.getInstance() );
}
}
Here is the PanelA class
public class PanelA extends HTMLPanel
{
private static PanelA panel;
private PanelA()
{
super("Panel A");
final RootPanel rootPanel = RootPanel.get();
Button btnNewButton = new Button("Go to panel B");
btnNewButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event)
{
rootPanel.clear();
rootPanel.add( PanelB.getInstance() );
}
});
add(btnNewButton);
}
public static PanelA getInstance()
{
if (panel == null)
{
panel = new PanelA();
}
return panel;
}
}
My other PanelB class is pretty much the same as PanelA , ie button that brings me back to PanelA
My UI works as desired.
My Question is, Is this singleton type pattern a correct or proper way to do this? ie Have a stack of Singleton UI views that get popped on/off the main panel?
Also, what is the best way to handle hitory/breadcrumb trace through a GWT app, ie allowing a user to go back to the previous screen bearing in mind that they may navigate to PanelX from either of PanelA, PanelB or PanelC
I use "Activities and Places" to manage all of this, and it's been working quite well in production for a year or so.
https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces
I think it's fine to use a Singleton mechanism for your views, but you have to make sure to completely reset any state you store. For me, it was easier to just create new views every time the user navigates to a new spot, and then if I detected a problem with load times or something to retroactively cause the view to re-use its components. I'd advise you to get the navigation working first, and then worry about the singleton (or not) optimizations.
I recommend Activities and Places design pattern.
It covers all the issues you raise in your question, plus many more that you have not thought of (or did not ask about) yet, like native browser history management and ability to bookmark different places within the app, handling of page reloads, efficient memory management vs optimized DOM operations, scalability (building an app with dozens/hundreds of views with minimal code duplication), testability, and code-splitting (where to split large apps).
I suggest you refer "GWTP" framework to make a GWT Project, some of the features currently supported by GWTP:
Dependency injection through GIN and Guice;
Simple but powerful history management mechanism;
Support for nested presenters;
Lazy instantiation for presenter and view;
Effortless and efficient code splitting;
Integrated command pattern supporting undo/redo;
So your questions and query like Singleton UI views, best way to handle hitory/breadcrumb trace and singleton type pattern , will cover and one good framework will make easy project management.
I am beginner in gwtp and I want to build an application that displays a list of products, and by clicking I displays the details of the selected product...
My question is how to refresh the page to allow page product Detail to refresh while respecting security measures, obviously I do not want to pass the id of the product in the request.
I thought about storing the id in the session but I do not know if it will impact the application's performance given the high response times of RPC.
Any help or clarification on this would be appreciated.
You might consider using GWT's Cookie Support. Properly implemented, you'd always know exactly what they were doing last and getting them back to there becomes easy. Cookies are obviously client-side, so it's always going to be faster than RPC.
I have some advice but be aware I'm fairly new to GWTP as well....
Security
Communication should take place over SSL/HTTPS. I put it across my entire app using the servlet container (web.xml) so that it integrates seemlessly with non-GWT parts of my app.
I don't see a problem with putting an 'id' in a url. You can always prevent it from showing in the address bar with PlaceManager.revealPlace(PlaceRequest, boolean).
Composed View
I have a view with a list of entities on the left and the edit form on the right. The list is always shown and is placed in a 'slot' explicitly by a parent presenter:
public class Users extends Presenter<Users.View, Users.Proxy> {
#ContentSlot
public static final GwtEvent.Type<RevealContentHandler<?>> LIST_SLOT = new GwtEvent.Type<RevealContentHandler<?>>();
#ContentSlot
public static final GwtEvent.Type<RevealContentHandler<?>> FORM_SLOT = new GwtEvent.Type<RevealContentHandler<?>>();
#Inject
private UserList userList;
#Inject
public Users(EventBus eventBus, View view, Proxy proxy) {
super(eventBus, view, proxy, Configuration.SLOT);
}
#Override
protected void onReveal() {
super.onReveal();
setInSlot(LIST_SLOT, userList);
}
...
My app has an 'empty form' presenter which is shown by default when no list item is selected. This prevents the list and parent presenters from being a 'place' (requiring a token). Only the leaf presenters in the presenter hierarchy should be a 'place'.
I am new to GWT, I would like to use hyperlinks where I would like to redirect the user to another form.
My question is that , creating hyperlinks are easy, but how do I use them ?? addClickListener seems to be deprecated, is there any other way to go around this ?
Update 1
I have implemented the Hyper link code as follows :
Hyperlink link0 = new Hyperlink("Show Boxes","showbox");
History.addValueChangeHandler(this);
History.fireCurrentHistoryState();
public void onValueChange(ValueChangeEvent<String> event) {
String eventValue=event.getValue();
if(eventValue.equals("showbox")){
showBox();
}
}
With this I see that the form corresponding to one hyperlink is visible, but this form is not closed and another for is not being opened when I click one another hyperlink.
I am using DockPanel to display the form in the East direction. The forms for all the hyperlinks are just being displayed one below the other.
Any comments/suggestions for the same ?
Thanks,
Bhavya
Use the Anchor.addClickHandler() method!
Anchor a = new Anchor("text");
a.addClickHandler(new ClickHandler(){
// etc
});
If the another form is within your GWT application, then you should consider using Hyperlink. In constructor you provide a history token which is pushed to History object when link is clicked. You just need to handle event that a history token has changed. It decouples navigation events from your logic. This will also make your application aware of back-forward and allows users save bookmarks to specific state (form in your case). Anchor is intended more for external links.
See it described in Coding Basics - History .
First you need to create a HyperLink with a history token:
Hyperlink link = new Hyperlink("link to foo", "foo");
In above example, "foo" is the history token.
Then you should register your value change handler on History object, like
History.addValueChangeHandler(myValueChangeHandler);
In your value change handler, you will need to read in the current token using event.getValue().
class MyValueChangeHandler implements ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
//get the new value of history token
//clicking on above example link will return "foo" here
String historyToken = event.getValue();
}
}
What does the value of history token means is up to your application to decide. For example you can maintain a simple Map between history tokens and the view that should be rendered. In more sophisticated applications you can encode more details into the token -- like initial state of the form that should be displayed.
im new to GWT ive been working on it since recently..
i want to know how can i go from "entry point page" ie,ImageViewer.java..
ive been suggested to create the memory by calling constructor on a perticular button
Button button = new Button("New button");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event)
{
new LookupMaster(); //this is a composite
}
});
but this is not working.. i guess v can only call or get alert messages using this type..
can some one help me.
I'm not sure how to answer, since I have the feeling you're not understanding the basic concepts totally, but that's just my interpretation.
GWT is one html page that via JavaScript methods changes the content of that one page. When you want to display 'another' page you need to do this via methods that update the html dynamically. Since you are just starting with GWT, you might want to read this page on Build User Interfaces to understand the concepts and look at some examples provided with GWT.
i am developing an application in which i have a logout option at all the forms. When i click that button I have to return to login form which is the first form to be displayed . So i am able to track back to the first from by making a new object of this from by the way this idea is bad to implement because the other froms are also in the stack. My question is how will i go to that first form while the other form objects are distroyed.
The whole idea is about login-logout functionality in winMo app. If somebody can help me with some part of code it will be very great.
Regards,
Madhup
The easiest way is to pass a reference to the Log-in form to all other forms. Avoid creating and destroying forms. Since you know you are going to reuse them, create them only once and then show or hide them.
In log-in form:
if (isLoginSuccessfull) {
newForm.SetParentForm(this);
newForm.Show();
// Do not call Close();
}
In secondary-forms:
public void SetParentForm(Form parent) {
this.parent = parent;
}
// When you need to close the form:
parent.Show();