Retour sur QCon London 2012

J'ai eu l'occasion cet année d'être envoyé par ma société, Objet Direct, assister aux 3 jours de la conférence QCon à Londres. Une excellente expérience, qui m'a permise de voir des présentations très variées aussi bien techniques que méthodologiques. Ça fait du bien de sortir de la mission pour aller voir ce qui se fait ailleurs et ça permet de revenir avec pleins d'idées de nouvelles et de motivation.

J'espère pouvoir appliquer toutes les bonnes pratiques que j'ai appris là bas prochainement.

J'ai écrit deux articles pour le blog d'Objet Direct :

  • Une synthèse succincte des 3 jours : QCon London 2012
  • Un retour plus détaillé sur une présentation que j'ai particulièrement aimé sur GitHub : "How GitHub Works"

Bonne lecture !

Wordpress login form with GWT and UiBinder

Following my previous post, I have decided to rewrite the example of the Wordpress login form using only UiBinder and the ClientBundle/Css features that comes with GWT. This example demonstrate how you can use only htmlPanel and UiBinder to build a perfect pixel Ui just with hmtl/css and no gwt panel.

You can see the result there. Or you can download and run the eclipse project from there.

To start I've just copied the html from my wordpress login page into the htmlPanel. Then I've renamed all the "id" on the divs into class, because gwt will only compile the css declared in the UiBinder into class css. I've replaced the <form> by a <div>. I've added some more styles and the image directly in the UiBinder, so GWT can compress and obfuscate it. In the application.css I've just added two styles for the body.

The main file that you want to see is WpForm.ui.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ui:UiBinder SYSTEM "">
<ui:UiBinder xmlns:ui=''

    <ui:image field='logo' src='logo-login.gif' />

        .form {
            margin-left: 8px;
            padding: 16px 16px 40px 16px;
            font-weight: normal;
            -moz-border-radius: 11px;
            -khtml-border-radius: 11px;
            -webkit-border-radius: 11px;
            border-radius: 5px;
            background: #fff;
            border: 1px solid #e5e5e5;
            -moz-box-shadow: rgba(200, 200, 200, 1) 0 4px 18px;
            -webkit-box-shadow: rgba(200, 200, 200, 1) 0 4px 18px;
            -khtml-box-shadow: rgba(200, 200, 200, 1) 0 4px 18px;
            box-shadow: rgba(200, 200, 200, 1) 0 4px 18px;
            font: 11px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans",
        .form .forgetmenot {
            font-weight: normal;
            float: left;
            margin-bottom: 0;
        .button-primary {
            background: #2379a1;
            color: #ffffff;
            font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans",
            font-weight: bold;
            text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
            padding: 3px 10px;
            border: none;
            font-size: 12px;
            border-width: 1px;
            border-style: solid;
            -moz-border-radius: 11px;
            -khtml-border-radius: 11px;
            -webkit-border-radius: 11px;
            border-radius: 11px;
            cursor: pointer;
            text-decoration: none;
            margin-top: -3px;
        .login .form p {
            margin-bottom: 0px;
        @external gwt-Label;
        .login .gwt-Label {
            color: #777;
            font-size: 13px;
        .form .forgetmenot .gwt-Label {
            font-size: 11px;
            line-height: 19px;
            color: #777;
            float: right;
            margin-left: 5px;
        .form .submit {
            float: right;
        .form p {
            margin-bottom: 24px;
        @sprite .login h1 a {
            gwt-image: 'logo';
            width: 326px;
            height: 67px;
            text-indent: -9999px;
            overflow: hidden;
            padding-bottom: 15px;
            display: block;
        .nav {
            text-shadow: rgba(255, 255, 255, 1) 0 1px 0;
            margin: 0 0 0 8px;
            padding: 16px;
        .nav a {
            color: #21759B;
        .input {
            font-size: 24px;
            width: 97%;
            padding: 3px;
            margin-top: 2px;
            margin-right: 6px;
            margin-bottom: 16px;
            border: 1px solid #e5e5e5;
            background: #fbfbfb;
            color: #555;
        .backtoblog {
            position: absolute;
            top: 0;
            left: 0;
            border-bottom: #c6c6c6 1px solid;
            background: #d9d9d9;
            background: -moz-linear-gradient(bottom, #d7d7d7, #e4e4e4);
            background: -webkit-gradient(linear, left bottom, left top, from(#d7d7d7),
                to(#e4e4e4) );
            height: 30px;
            width: 100%;
        .backtoblog a {
            text-decoration: none;
            display: block;
            padding: 8px 0 0 15px;
            color: #464646;
        .login {
            width: 320px;
            margin: 7em auto;
            padding-top: 30px;

        <div class="{style.login}">
                <a title="Propulsé par WordPress" href="">Le blog de Raph</a>
            <div class="{style.form}">
                    <br />
                    <g:TextBox styleName="{style.input}" />
                    <br />
                    <g:TextBox styleName="{style.input}" />
                <p class="{style.forgetmenot}">
                    <g:Label> Se souvenir de moi</g:Label>
                <p class="{style.submit}">
                    <g:Button styleName="{style.button-primary}">Connect</g:Button>


            <p class="{style.nav}">
                <a title="Récupération de mot de passe"
                    href="http:///">Mot de passe oublié ?</a>
        <p class="{style.backtoblog}">
            <a title="Êtes-vous perdu(e)?" href="/">← Retour sur Le blog de

WpLogin.css :

* {
        margin: 0;
        padding: 0;
    body {
        font: 11px "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans",
            sans-serif !important;
            background-color: #f9f9f9 !important;

And that's all ! So now, please don't follow the advices of writing all your html in a big static String and learn how to use the tool !

Happy coding !

Result page Or you can Download the eclipse project

GWT and HTML under control

In the past weeks I've seen two articles about making clean design with GWT. That was really interesting, but something still stugling me a lot. Both authors agreed not to use layout widgets provided by GWT to build UI neither UiBinder but use instead a big ugly static String to store an HTML code/

Take a closer look at those two articles and come back later to find out a better way to improve your design based on GWT.

Lightweight GWT layouts

Tags first GWT

The purpose is to write a clean HTML with the least number of tags and have that HTML code under control with only CSS. I do agree that using the old GWT layout system is a really mess producing a lot of tables and ugly code.

However, since GWT 2.0, Google brought us a better layout system with the widgets positionned using only div and css. With this system you can normally reach a clean design without generating table tags and a lof HTML mess.

But since the web is all about simple html and css, I agree with Zack Grossbart that you need to have a perfect control of your UI with the least html tags and just css.

But with the version 2.0 GWT also introduces a wonderful feature called UiBinder. With UiBinder you can describe in a declarative way your design separated from your logic. You can especially use the HtmlPanel panel to mix up classic HTML/CSS and GWT widgets. This is exactly what they wanted to do ! Use classic HTML and CSS to describe the UI and GWT only for the control. By using UiBinder they can take advantage of a powerfull tool having a built-in feature to bind GWT widgets from the xml to the Java and many mores.

Putting your html within a static String is not really that clean and maintainable. So please, for God sake, do not do it ! Learn the API and follow the best practices.

[update] I've now coded a rewrite of the wordpress login page example just by using UiBinder and the HtmlPanel, see this post.

How-To change the style of your GWT 2.1 ValuePicker ?

This class demonstrate how-to change the style of the GWT 2.1 ValuePicker.

public class Main extends Composite {
    private static class DefaultCell<T> extends AbstractCell<T> {
        private final Renderer<T> renderer;

        DefaultCell(Renderer<T> renderer) {
          this.renderer = renderer;

        public void render(Context context, T value, SafeHtmlBuilder sb) {
    public interface MyResources extends CellList.Resources {
        Style cellListStyle();
    Renderer<String> renderer = new AbstractRenderer<String>() {
        public String render(String object) {
            return object;
    private static MyResources RESOURCES = GWT.create(MyResources.class);

    private static final Binder binder = GWT.create(Binder.class);
    @UiField FlowPanel panel;

    interface Binder extends UiBinder<Widget, Main> {

    public Main() {

        CellList<String> cellList = new CellList<String>(new DefaultCell<String>(renderer), RESOURCES);

        ValuePicker<String> valueBox = new ValuePicker<String>(cellList);
        valueBox.setAcceptableValues(Arrays.asList("HELLO", "WORLD"));

Gwt – Surcharger les styles par défauts

La version 2.0 de Gwt à introduit l'interface CssResource qui permet de lier des classes css à des widgets Gwt en java. Cette interface permet de bénéficier d'optimisation à la compilation et de brouiller les noms des classes pour éviter les collisions. Elle enrichi aussi la syntaxe Css, par exemple en permettant de déclarer des constantes. Il est ainsi très facile de déclarer des feuilles Css qui joueront le rôle de feuille parent de laquelle hériterons les feuilles spécifiques à chaque partie de l'interface. Cela permet par exemple de créer très facilement plusieurs thèmes.

Cependant, il n'est parfois pas aisé de surchargé les styles du thème par défaut. En effet, l'interface les styles déclarés avec CssResources sont injectés uniquement quand nécessaire, et parfois après ceux de la feuille de thème par défaut qui les surchargent donc. Pour pallier à ce problème, il existe une astuce c'est d'utiliser l'annotation @External

public interface WidgetCss extends CssResource {
        public void myButtonStyle();

public interface WidgetResources extends ClientBundle {
        public WidgetResources INSTANCE = GWT.create(WidgetResources.class);

        WidgetCss css();

Fichier css :

@External .gwt-Button
.myButtonStyle .gwt-Button{
    color: #424242;
    font-size: 13px;
    cursor: pointer;

Utilisation :

public MyWidget() {
    Button button = new Button("click me !");

* @return Helper access to the css String;
private WidgetResources css() {
    return WidgetResources.INSTANCE.css();

Et voilà, la déclaration du thème par défaut gwt-button est maintenant surchargée par myButtonStyle.

Le style ne sera pas surchargé par le thème par défaut, et il n'est pas nécessaire un moche hack avec par exemple "!important".

Bon gwt à tous !