Is this an acceptable GWT solution - gwt

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.

Related

GWT: Creating a new object when I click on a button

When I try to create a new object at clicking a button, the created object does not look okay.
This is what I do:
#UiHandler("button")
protected void onButtonClick(ClickEvent e) {
RootPanel.get().clear();
RootPanel.get().add(new UserLandingPage());
}
The GWT way of switching from a set of widgets to a totally different one is through Activities and Places.
All you need is to follow the google examples on how use the MVP framework.
I collected some demos at the repo below, if you have any doubt don't hesitate to comment and ask further:
https://github.com/jimmyfm/gwt-mvp-examples
Another solution may be to put an HTMLPanel in the root and then switch widgets inside the HTMLPanel by calling
addAndReplaceElement

How to switch between UI implementations in run-time?

I'm developing an application using GWT 2.6.
Now I have a task to implement a functionality to switch between simple/expert modes (of view) at run-time. It means to show a simplified version of view which may contain another widgets.
But the problem is that all the views in most cases are "static" and defined as singletons (using GIN).
Is it possible to implement this using only GWT and what should I use to make it?.
There are many ways that this can be done. A couple of ideas that spring to mind:
Option 1.
Instead of using GIN to inject the view, inject a view provider (com.google.inject.Provider). This can be used by the code that builds the view (the activity?) to get the view. The implementation of the view provider can then return an implementation of the view for the relevant mode, simple or expert. For example,
#Inject
public ComposeMessageActivity(Provider<ComposeMessageView> viewProvider, ...) { ... }
#Override
public final void start(final AcceptsOneWidget panel, final EventBus eventBus) {
view = viewProvider.get();
Option 2.
Use deferred binding. This is not so dynamic but has the advantage a simple implementation will be a smaller download than an expert implementation. There is a project, gwt-seminar, on github that shows this in practice that has mobile and desktop versions.

What is the best way to allow page refresh in gwtp?

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'.

Dealing with model save and update with GWT Platform

I'm trying to adapt my GWT web application from my home-grown MVC to GWT Platform.
I've managed to port the my application views with presenters, and essentially able to access views via PlaceRequest. And with changing the URL (#).
However I am not sure how to deal with Models using this GWT platform, in the common MVP I know there is a go() method in the presenter which fetches data, say from server via RPC.
In the GWT platform presenter here are the methods automatically generated by the Eclipse plugin:
Constructor
revealInParent
onBind
onReset
Where should I put the RPC code that will fetch and update my model. Say in the presenter I have:
ProfilePresenter.java:
public class ProfilePresenter
extends
Presenter<ProfilePresenter.MyView, ProfilePresenter.MyProxy> {
public interface MyView extends View {
HasText getFullname();
HasText getLocation();
HasText getAboutme();
HasText getLastlogin();
}
private User user; // Model which represents the User information etc.
And when the View associated with the Presenter is shown I need to fetch the User model from the server and update the model and then subsequently update the view through the interfaces it expose.
Also, say I have some buttons in the view, which then can be accessed by the presenter through HasClickHandler where should I put the event handlers?
I would put the RPC call in the onReset method.
See the presenter lifecycle
Personally I deal with events using the reversed MVP pattern. But you can also call a handler this way:
getView().getSubmitButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
}
});
with the following signature for getSubmitButton in your view interface:
HasClickHandlers getSubmitButton()
Sydney covered most of your questions.
In general onResetmethod is a good place to make backend calls.
Sometimes when the backend call takes longer and you want to display the view only after the data was loaded you can use manual reveal.
But for the profile page I don't think that is necessary.
I also agree with the reverse MVP pattern. It's way easer to test presenters using the reverse MVP Pattern than using the HasXXXHandlers interfaces.

How to keep business logic seperate within GWT Composites?

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.