Using mgwt for desktop and mobile applications - gwt

I have an application written in GWT. I want to be able to provide a subset of the same application for use when the site is opened in mobile browsers, and have been looking at mgwt as a way of achieving this.
The way I am expecting it to work is that I will augment my existing GWT application project with mgwt code (with some logic sharing) resulting in two entry points. My question is how to manage this given a single html page? I have seen the approach described in this article and was wondering whether that will work well with mgwt or whether there should be another pattern I should be considering?

I don't think you need 2 entry points. As kiran said above, you should reuse all the code except the view components. In case you used the GWT Activities and Places module, the view components should be completely decoupled from the rest of the code.
In this case you can use the the GWT.create method associated with the correct definitions in the module xml definition:
//in your entry point:
private IClientFactory clientFactory = GWT.create(IClientFactory.class);
//in your module xml definition:
<replace-with class="com.vv.xui.client.DesktopClientFactory">
<when-type-is class="com.vv.xui.client.IClientFactory" />
<when-property-is name="formfactor" value="desktop"/>
</replace-with>
<replace-with class="com.vv.xui.client.MobileClientFactory">
<when-type-is class="com.vv.xui.client.IClientFactory" />
<when-property-is name="formfactor" value="mobile"/>
</replace-with>
The form formfactor property can be defined as in this example:
https://code.google.com/p/gwt-cx/source/browse/trunk/gwtcx/gwtcx-core/gwtcx-core-client/src/main/resources/com/gwtcx/FormFactor.gwt.xml
In your IClientFactory you will have something like this:
public interface IClientFactory {
IHomeView getHomeView();
ISearchView getSearchView();
...
}
Where IHomeView and ISearchView are the view interfaces implemented by the desktop and the mobile versions. In my case the View implementations are UiBinder components that implement the associated view interface.
In your DesktopClientFactory you will have something like this:
public class DesktopClientFactory implements IClientFactory {
private static final ISearchView searchView = new com.vv.xui.client.view.desktop.SearchView.SearchView();
#Override
public ISearchView getSearchView() {
return searchView;
}
...
}
In this way you don't need different entry points for mobile and desktop and can share all the code except the view components.

That pattern in the link pointing to MobileWebApp on googlecode is correct. Basically you have UI view interfaces in GWT which stick to MVP pattern recommended on GWT. Then you can do different implementations of the UI Views based on the screen resolutions available. Obviously you don't want the same screen lay outs on desktop and mobile. So you will need to redesign your views for different form factors and then call the correct implementations based on the form factor the device. Since you already have a gwt application, you can create views for mobile using mgwt and reuse the code that you already created. But still you will have to create new views for mobile using mgwt, it wont be a straight forward replace.

Related

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.

GWT: MVP Presenter Interface

I try to understand how the gwt example about activities and places works (https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces). I am wondering why they define an interface for the presenter. I know the view interface is helpful to exchange the view easily. But what's the use of the presenter interface?
Its always a best practice to design application with interfaces rather than concrete classes.
Reference - What does "program to interfaces, not implementations" mean?
Reference - WikiPedia example for MVP
Another key factor in MVP architecture to make your design pretty clean is defining an Presenter interface(As we already know the beauty of interface OOP conceptin JAVA).
Presenter interface that allows our View to callback into the presenter when it receives an event. The Presenter interface defines the following:
public interface Presenter<T> {
void onAddButtonClicked();
}
And then you can set the presenter to your view like below
private Presenter<T> presenter;
public void setPresenter(Presenter<T> presenter) {
this.presenter = presenter;
}
Finally when your PresenterConcreteClass implements your presenter interface those implementations will triggers.
Besides the cleanliness of using an interface, there's also no reason you wouldn't test your view. You could use end-to-end tests, but you can also simply use a GWTTestCase where you instantiate the view and use a mock presenter.
You'd then be able to test that “when I click on this button, it should call this method from the presenter with the values X, Y and Z as arguments”, or “when I call this method of the view with those arguments, then such widget should turn red and that other one should hide/collapse/show/whatever”.
I've also used it, once, to similarly build a simple testbed app to manually test the UI with fake data. The app consisted of buttons to simulate the presenter calling the view with fake data, and handled the presenter calls back from the view with Window.alert or similar things. You'd launch the app in your browser and click here and there and validate that the view works as expected.
This can be useful when you later add a field to your form, to make sure you correctly wire it with the presenter. You don't want to setup your GWT-RPC/RequestFactory/whatever services from the real presenter, when a unit-test could be enough.
2 big reasons off the top of my head (there may be others too...)
Testing: Your Presenter then does not have to have a direct reference to the View, which is nice because the View contains GWT Objects (i.e: any Widget) which cannot be used in a standard Unit Test Case: Any GWT Object must have a JS container (i.e: Browser, or GWTTestCase) to be instantiated; A JUnit test case cannot use a Browser; GWTTestCase runs VERY slow, so you should prefer not to have to use it. Without the interface, the Presenter would have to reference the View's methods by a direct reference to the View; that means when testing the Presenter, you must instantiate the View, which must instantiate its Widgets (which at that point require the GWTTestCase for the Widgets). And all you should be aiming to do in the 1st place is to test the logic, which should be completely in the Presenter to avoid GWTTestCase... With the Display interface, you can do just that: Focus on testing the Presenter, without the complication of instantiating the View (which has its own degree of instantation complication) and messing around then necessarily with GWTTestCase
Have multiple Views for the same Presenter: [I think you would only ever do this if you have different platforms (i.e: mobile App vs. browser) which each require their own View (since a mobile App version of the View is rendered differently from a browser View, since they are different platforms with different GUI entities)]. The multiple Views would then all just implement the Display interface in their separate ways. Then the single Presenter can contain the logic that is the same for all Views, be used for all the different Views, and all View implementations are guaranteed to follow the same expectations (which are the codification in the Display interface) of that single Presenter! This is a manifestation of the OOP best practice of designing with interfaces, which #SSR Answers.

GWT: formfactor dependent editor

I'm developing a web app for different formfactors. Each has its own client factory to create formfactor dependent views. Everythings works fine so far but I'm stuck when it comes to the Editor Framework.
To make use of the framework I have to declare a marker interface like so:
interface Driver extends SimpleBeanEditorDriver<User, UserEditor> {}
Since this happens in my formfactor agnostic activity I want the type UserEditor to refer to the actual implementation based on the formfactor, i.e. UserEditorPhone, UserEditorTablet, UserEditorYouNameIt.
To no avail I tried using deferred binding in module.gwt.xml:
<replace-with class="com.example.client.desktop.UserEditorDesktop">
<when-type-is class="com.example.client.view.UserEditor"/>
</replace-with>
Any ideas on what I'm missing and how to avoid having a one-to-one-relationship between formfactors and UserEditor-activities?
You'll want your formfactor-agnostic activity to only know about SimpleBeanEditorDriver<User, ?>, and move the Driver interface into each one of UserEditorDesktop, UserEditorTable and UserEditorPhone.
The activity will then ask a formfact-dependent object (e.g. its view, if you use MVP and the activity is the presenter) for an instance of the editor driver rather than using GWT.create() directly.
(I can give code sample if you detail how your code is organized: are you using MVP? is the editor your view? how's it instantiated? etc.)

SWT Controls with predefined styles

I want to have in my SWT project controls (Button-s, Text-s, etc) with predefined styles. My first idea was to extend for example org.eclipse.swt.widgets.Text class, set some settings and use that new classes instead of original, but get org.eclipse.swt.SWTException: Subclassing not allowed exception. How to do that right ?
You have to override checkSubclass method to do nothing, otherwise it will complain that subclassing not allowed - because usually you shouldn't really override standard components.
#Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
You also should consider building custom widgets containing primitive controls using delegation. For example you can build MyText which will contain Text widget inside with custom setup.
Thing to remember is SWT provides standard controls which looks natively on each on platform. Anyway polishing standard components is still allowed and even a must in production software.
See the SWT Faq for this concern. There you'll find also a link howto write custom widgets

How to write completely custom widgets recognizable by GWT Designer?

When I add let's say, a standard GWT VerticalPanel, with GWT Designer I can add widgets to this panel by drag and dropping them. GWT Designer provides a red line indicating I am adding a widget to my VerticalPanel.
Suppose that I want to create my own panel from scratch, and I don't want to extend standard GWT panels. I want GWT Designer to recognize my panel and provide the same functionality it provides when I use standard gwt panels.
As far as I know frameworks such as Ext-GWT wrote their widget libraries from scratch and yet they work in unison with GWT Designer. Do I need to implement certain methods in my custom panel to achieve this functionality? Any guidance or ideas are well appreciated.
Thank you
To summarize, support for a new component requires adding special support for this component into GWT Designer. Assume I have a custom component which I want it to act like a VerticalPanel but which infact is type composite :
public class CustomPanel extends Composite implements HasWidgets{
private VerticalPanel panel = new VerticalPanel();
public CustomPanel() {
initWidget(panel);
}
#Override
public void add(Widget w) {panel.add(w);}
#Override
public void clear() {panel.clear();}
#Override
public Iterator<Widget> iterator() {return panel.iterator();}
#Override
public boolean remove(Widget w) {return panel.remove(w);}
}
This will work as a VerticalPanel, but when you are looking from the Designers perspective this still is a Composite. As a result you can not drop widgets inside it. In the simplest case, what you should do to make it designer friendly is to create a CustomPanel.wbp-component.xml in the same package of CustomPanel following given name convention. A simple one to give flow like widget adding behaviour would be,
<?xml version="1.0" encoding="UTF-8"?>
<component xmlns="http://www.eclipse.org/wb/WBPComponent">
<description>This is a simple Composite acting like VerticalPanel</description>
<!-- CREATION -->
<creation>
<source><![CDATA[new org.test.client.CustomPanel()]]></source>
</creation>
<parameters>
<parameter name="flowContainer">true</parameter>
<parameter name="flowContainer.horizontal">false</parameter>
<parameter name="flowContainer.association">%parent%.add(%child%)</parameter>
</parameters>
</component>
After adding this step your composite should be treated like a vertical panel (dropping widgets inside support) by the gwt designer as well. When this XML alone is not enough, meaning you need some behavior more of a complex nature, you need to start writing java model classes that defines custom behaviour of your component to Designer and reference it in your component xml using <model> tag. In this case you need to write a plugin to host your models and policies.
Here are the references for this summary and useful links:
Google groups question answered by WindowBuilder team
http://code.google.com/intl/tr-TR/javadevtools/wbpro/DesignerCustomizationAPI.pdf
http://code.google.com/intl/tr-TR/javadevtools/wbpro/NewComponentsTutorial.pdf
http://en.wikipedia.org/wiki/MVEL
GWT Designer documentation have a page about custom composites and panels but these pertain to Swing and SWT components. As for GWT, the documentation recommends using GWT's layout managers for maximum portability.