Thursday, April 5, 2018

MVP4G2 RC 2 is out!

MVP4G2 RC 2 is out!

This version fixes some issues related to the recompile and should be nearly ready to use with J2CL one it is available!

There is one known issue, which will be fixed with the next release candidate: The debug option will print debug informations in prod mode on the console. This problem will be fixed with release candidate 3.

Maven Central is updated!

Wednesday, February 7, 2018

MVP4G2 Beta 2

I just have updated mvp4g2.  

One of the major change is, that the historyOnStart-attribute has been remove from the @Event-annotation and been added to the @Application annotation.

Besides that a new feature is implemented that changes the way events and event handlers are defined. Now, it is no longer necessary to use the handler- or broadCast-attirbue inside the Event annotation to bind a presenter to an event. All you have to do now, is to define an event inside the event bus and annotate a method with @Event.

An event definition will look like this: 

@Event
void gotoDetail(long id);

Add this code to a mvp4g2 based  presenter or handler:

@EventHandler
public void onGotoDetail(long id) {
...
}

That’s all. Mvp4g2 will wire up the event with the handler method.

Of course the handler-attrnute as most of the other attributes from the mvp4g Event-annotation are still supported. 

You will find a list of features currently  implemented in mvp4g2 here: https://github.com/mvp4g/mvp4g2/wiki/Comparision:-Mvp4g-vs.-Mvp4g2

All examples have been updated.   

Next thing will be the implementation of the multi module feature.

Saturday, December 30, 2017

Future of Mvp4g

At GWTCon 2017 in Florence Colin Alworth announced that Google has given access to J2CL for a small group of people outside Google and the work on GWT 3 has been started.

J2CL and GWT 3 will bring major changes to the GWT development.

As far as we know today, we will miss a lot of things we have in GWT 2.x:
  • JSNI will be replaced by JsInterop
  • Generators will be replaced by APT
  • the widget system will be gone
  • modules like editor, rcp, place management, events, etc. have to be updated 
(The people from vertispan are working on it. If you like to support them, get in contact with Colin!)

Looking at mvp4g 1.x we can say, that it will not work with J2Cl without a major reengineering. mvp4g 1.x is based on a generator and has dependencies to several third party libs. Generators will be gone in J2CL / GWT 3 and some of the third party libs will not work (f.e.: GIN).

A few month ago, the work on mvp4g version 2 started. The goal is to implement a new version of mvp4g, which will work with J2CL and GWT 3. In December 2017 I made the beta of the new version public.

You will find mvp4g2 here: mvp4g2

A lot of the mvp4g features are already implemented, some feature have changed, some features will be dropped and new features have been added.
For example a loader at application start feature is added and a new way to add a presenter/handler to the event bus. 

A list of currently implemented, changed or dropped features can be found here:  Comparsion: Mvp4g vs. Mvp4g2. We will work on mvp4g2 so that it will be final once GWT 3 is available.

There are a few examples already implemented, that use mvp4g2 and different view implementations. The examples can be found here: mvp4g2 examples 

The example called 'Mvp4g2SimpleApplicationUsingElementoAndEventHandlerAnnotation' uses the new way of event handling registrations and Elemento to create the views.

During the next months I will follow up with more posts describing the changes of mvp4g2 more detailed.

Feedbacks are welcome.  

(Please, keep in mind, that mvp4g2 is still beta. The validation and error messages needs to be improved and the documentation is not up to date.)

new Gitter room

If you have questions or want to get in contact with the developers of mvp4g & mvp4g2, you can now use the newly created Gitter room: mvp4g & mvp4g2 Gitter room.

All you need to use it, is a GitHub account!

Tuesday, September 13, 2011

A Complex-Layouting Library over mvp4g

Hello, mvp4g blog readers! shaman.sir is speaking.

With gratitude to Pierre, I am here to present you an mvp4g extention that will allow you to build a portlet-oriented web-applications with mvp4g.

To provide you with quick example, here's a running demo: http://gwt-mvp4g-layouting-demo.appspot.com/

And here's the short summary of documentation pages:

mvp4g framework helps in writing applications which has not a lot of significant changes happening in the inner page section or just with a central part that is /instantly/ replaced with a new content. I can’t say that it is a limitation of the framework — this situation may change in near future or, in fact, it is may be not so required for a lot of users — however, for the moment, this fact takes place and it was required for us in developing experika.


This library listens for every history event that happens in your application, finds what widgets layout to use for current page, and if it needs to rebuild the page, it rebuilds it and fills with new widgets (and if just part of page needs to be redrawn, it redraws only this concrete part). And only then it calls an appropriate navigation event. When you describe the layout, you just specify the placeholders for widgets, and there are special LayoutBuilders who fill the layout with widgets depending on current page and its state (it is true, support states like Loading/NothingFound/NoMatches/SomethingFound, you can easily switch them from inside the Presenters).


A library is in the stage of discovering final bugs and plans on improvement, so if you'll find a bug or want to offer some good idea, please issue it.

Here the links go:


Also, I need to mention people who helped me with this framework:
  • Vitaly Gashock, who introduced mvp4g to me and who gave me the idea to make "everything like portals" :).
  • Sergey Dyniovsky, who gave advices on how it will be easier to apply a CSS markup to resulting pages






Thursday, August 11, 2011

Custom Place Service

History management is probably one of the features with the most impact on user's experience and on your application architecture. In Mvp4g, it is also one of the most customizable features. This feature is organized around a Place Service and since 1.3.0, you can easily set your own. You can then override 100% of the default place service or you can just change part of it to manage history exactly the way you want.

In this tutorial, we're going to cover one of the most common cases to set a custom place service, changing characters used in the URL to separate the event name from the parameters. We will reuse the example from the previous post and add a custom place service. You can download the example here (Project: Mvp4g_Custom_Place_Service).

Creating a custom Place Service

To change the parameter that separates the event name from the parameters in the URL, all you have to do is create a class that extends PlaceService and override the getParamSeparator method.
public class CustomPlaceService extends PlaceService {

    protected String getParamSeparator() {
        return ":";
    }

}

Setting a custom Place Service

To set a custom place service, you need to annotate your event bus with @PlaceService and set the class of your place service.
@PlaceService( CustomPlaceService.class )
@Events( ... )
public interface CustomPlaceServiceEventBus extends EventBusWithLookup {
    ...
}
Mvp4g will then use this class to instantiate it.

You have now created and set a custom place service that will replace the default place service.

Particular case: “/”

You can use “/” to separate event name from the parameters but an extra step is required. This character is a particular case because it is also used to manage child modules history. To sum up, when you store an event of a child module in the history, the child module name followed by “/” is added to the event token. By default, you then have something like this:
childModuleName/eventName?parameters
So, if you set the “/” to separate event name from the parameters, your token looks like this:
childModuleName/eventName/parameters
If the event doesn't have any parameters, you will then have the following token:
childModuleName/eventWithNoParameterName
The issue here is this token won't be interpreted the way it is expected. Since there is only one “/” in this token, Mvp4g will assume it is used to separate parameters from the eventName so it will parse 'childModuleName' as the event name and 'eventWithNoParameterName' as the parameters.
To solve this issue, we need to make sure a “/” is always added to the token after the event name even if there is no parameter. Thus the previous token becomes:
childModuleName/eventWithNoParameterName/
To do this, we're going to modify our custom place service to change the default behavior. The PlaceService object uses a 'tokenize' method that generates a token from the event name and its parameters string representation. You can then override this method to automatically add “/” after the event name.
@Override
public String tokenize( String eventName, String param ) {
    //always add the paramSeparator since "/" is used 
    //for module separator and paramSeparator
    String token = eventName + getParamSeparator();
    if ( ( param != null ) && ( param.length() > 0 ) ) {
        token = token + param;
    }
    return token;
}
We now have created a custom place service where “/” is used as a separator.

What's next?

This tutorial is quite short and simple but it covers, I believe, one of the most important features to be aware of. Mvp4g provides a default mechanism to generate and retrieve the history token but it's entirely up to you to have the one you want. The part you have to override will depend on the changes you want to bring. If you want to modify the entire logic, you will probably have to override the 'convertToken' and 'place' methods. If you'd just like to alter the default generated token, you will most likely be looking at the 'tokenize' and 'parseToken' methods.

You can also create a custom place service not to modify Mvp4g logic but to add another action when the token changes. For example, you could easily add Google Analytics to your application:
public class CustomPlaceService extends PlaceService {
    ...    
    public String place( String eventName, String param, boolean onlyToken ) {
        //send info to Google Analytics
        sendToGoogleAnalytics(eventName);
        
        return super.place( eventName, param, onlyToken );
    }
}
This is probably a good example to develop in more details in a future post.

Wednesday, July 20, 2011

Hyperlink Navigation

Building your application navigation with hyperlink can improve user's experience. He can then navigate the same way through your website as he would on a non-ajax website. Hyperlink gives him access to familiar link functionalities like the over state to display the link in the status bar or the right click to open the link in a new tab or copy it.

One feature introduced with Mvp4g-1.3.0 is the hyperlink token generation, which easily creates the token associated to an event. In this tutorial, we're going to modify our previous example to use hyperlinks for our menu. You can download the example here (Project: Mvp4g_Hyperlink_Navigation).

Impact of Hyperlink Navigation


Using hyperlink will impact how you can build your navigation. The first main impact is when you retrieve parameters associated with your navigation. With regular navigation, you get your parameters after the user's action to navigate. The most common case is that you retrieve your parameter in the click handler after the user clicks on your menu.
On the other hand, you build your token for the hyperlink before you display it. You will then need to retrieve your navigation parameters before user's action. With hyperlink token, you will also have to decide when to build your token. Is this token static? Then you can build it once, when you build your hyperlink widget. If not, you may have to build it every time you display it.

The second main impact concerns Mvp4g and how the navigation is going to be treated. When you use regular navigation, you usually fire an event that is forwarded to a handler. With hyperlink navigation, you actually change the history token. This change is handled by the GWT History class that forwards it to the Mvp4g Place Service, which then uses a history converter to fire the appropriate event (which is then forwarded to the handlers). Thus with regular navigation, you only use the event bus whereas with hyperlink navigation, you go through the whole history process. I tried to summarize these differences in the following sequence diagrams:

Sequence Diagram for regular navigation
Sequence Diagram for hyperlink navigation


Changing the event bus to generate token


To generate a token for an event, it is quite easy thanks to the token generation feature introduced in Mvp4g-1.3.0. All you have to do is change the return type of the event method in your event bus interface from void to String. You can generate a token only for events associated with a history converter.

In our example, we need to generate tokens for goToPage1 and goToPage2 events (our place events):
@Events( startView = RootView.class, historyOnStart = true )
public interface HyperlinkNavigationEventBus extends EventBusWithLookup{

    ...

    @Event( handlers = Page1Presenter.class, historyConverter = PageHistoryConverter.class, name = "page1", navigationEvent = true )
    String goToPage1( String origin );

    @Event( handlers = Page2Presenter.class, historyConverter = PageHistoryConverter.class, name = "page2", navigationEvent = true )
    String goToPage2( String origin );

}
To generate the event token, you need to set the event bus in token generation mode by calling the getTokenGenerator method of the presenter. Then you can call your event method. Since the event bus is in token generation mode, this method will return the event token without actually firing the event.
String tokenPage1 = getTokenGenerator().goToPage1( "You clicked the menu." );
When you set the event bus in token generation mode, it will automatically go back to regular mode whenever you call an event method that can generate token (ie an event method that returns a String). If you don't call one of these methods, your event bus will stay in token generation mode.

Implementing hyperlink navigation for our example


For our example, we want to base our navigation on hyperlink. In order to do so, we need to change our menu.

The first thing we need to change is our menu interface. Instead of having the presenter provide two methods to go to other pages, the view will implement two methods to set each page token.
public interface IMenuView extends IsWidget {

    public interface IMenuPresenter {
        //nothing to implement        
    }
    
    void setPage1Token(String token);
    
    void setPage2Token(String token);

}
The next step is to generate the token for the hyperlink. Our tokens are static so we can generate them only once when we bind the view and the presenter.
@Presenter( view = MenuView.class )
public class MenuPresenter extends BasePresenter<IMenuView, HyperlinkNavigationEventBus> implements IMenuPresenter {
    
    @Override
    public void bind(){
        String tokenPage1 = getTokenGenerator().goToPage1( "You clicked the menu." );
        view.setPage1Token( tokenPage1 );
        
        String tokenPage2 = getTokenGenerator().goToPage2( "You clicked the menu." );
        view.setPage2Token( tokenPage2 );
    }

    ...
}
Finally we have to modify our menu view to use hyperlink widgets.
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui">
    <g:HTMLPanel styleName="menu">
        <table cellpadding="0" cellspacing="0">
            <tr>
                <td>
                    <g:Hyperlink ui:field="page1">Page 1</g:Hyperlink>
                </td>
                <td>
                    <g:Hyperlink ui:field="page2">Page 2</g:Hyperlink>
                </td>
            </tr>
        </table>
    </g:HTMLPanel>
</ui:UiBinder> 
We then need to use these hyperlink widgets to set the page token.
@Singleton
public class MenuView extends ReverseCompositeView<IMenuPresenter> implements IMenuView {

    ...

    @Override
    public void setPage1Token( String token ) {
        page1.setTargetHistoryToken( token );    
    }

    @Override
    public void setPage2Token( String token ) {
        page2.setTargetHistoryToken( token );        
    }        

}
We now have our example with a navigation system based on hyperlink.

What's next?

As you can see, building your application navigation with hyperlink is quite easy thanks to the new feature introduced in Mvp4g-1.3.0. Using hyperlink will greatly improve your user experience but you will have to make sure that the constraints that come with it can work for your project.

In the next post, I will describe another advanced Mvp4g feature to set your own place service.