Thursday, October 29, 2009

Getting started with Grails & SmartGWT

Read about the potential benefits of using the SmartGWT web GUI library here, here, here, here & here.


I believe, coupled to Groovy/Grails, this could be a killer productivity/maintenance win.


Here are some getting started instructions I gleaned from a Isomorphic SmartClient GWT forum thread:



  1. grails create-app test

  2. cd test

  3. grails install-plugin gwt

  4. grails create-gwt-module helloworld

  5. grails create-gwt-page helloworld/index.gsp helloworld

    1. Reply 'y' for "HelloworldController does not exist - do you want to create it now? [y/n]"



  6. Put SmartGWT statements into .\src\gwt\helloworld.gwt.xml

    <inherits name="com.smartgwt.SmartGwt"/>

    <inherits name="com.smartclient.theme.enterprise.Enterprise" />

  7. Put the workaround (described here) into the HTML HEAD section of grails-app\views\helloworld/index.gsp

    <script>

    var isomorphicDir = "${createLinkTo(dir: 'gwt/helloworld/sc/')}";

    </script>

  8. Copy the SmartGWT jar (i.e. smartgwt-1.3.jar) to lib/gwt e.g.

    1. md .\lib\gwt

    2. copy \tools\smart-gwt\smartgwtee-1.2\lib\smartgwt-1.3.jar .\lib\gwt\



  9. Copy the SmartGWT jar to your %GRAILS_HOME%/lib too (or Grails will fail when compiling) e.g.

    1. copy \tools\smart-gwt\smartgwtee-1.2\lib\smartgwt-1.3.jar %GRAILS_HOME%\lib\



  10. Compile GWT module with

    1. grails compile-gwt-modules

      --ignored warning:-------------------

      Warning, target causing name overwriting of name default

      [echo] Compiling GWT modules

      [echo] Module: helloworld

      [java] WARNING: 'com.google.gwt.dev.GWTCompiler' is deprecated and will be

      removed in a future release.

      [java] Use 'com.google.gwt.dev.Compiler' instead.

      [java] (To disable this warning, pass -Dgwt.nowarn.legacy.tools as a JVM arg.)

      ------------------:-------------------



  11. Test/run under GWT Shell with

    1. grails run-gwt-client

      1. This will launch the GWT Shell and the hosted GWT Browser

        1. The GWTShel will display the message: Starting HTTP on port 8888

        2. The GWT browser (launched by the Shell) wil display a HTTP 404 ERROR

          1. This is normal since the URL is incorect i.e. http://localhost:8080/test/

            1. Peek into "%HOMEPATH%\.grails\%GRAILS_VERSION%\projects\test\plugins\gwt-0.3.2\scripts\RunGwtClient.groovy" for clues:

              1. // The user can specify a host, a port, or both...

                1. grails run-gwt-client localhost:8888 launches the browser to http://localhost:8888/test/ which is closer to correct



              2. arg(value: "http://${targetServer}/${grailsAppName}")

                1. grailsAppName could be susbstituted (for what?) but I don't know the consequences of doing so. TBA







          2. The correct URL i.e. http://localhost:8888/helloworld/

            1. This page appears to be empty because the GWT entry point currently does nothing - it's empty

            2. If you right-click and choose View Source you'll see some content like this:


              1. <html><head>

                <script language='javascript' src='helloworld.nocache.js'></script>
                </head><body>

                <iframe src="javascript:''" id='__gwt_historyFrame' style='position:absolute;width:0;height:0;border:0'></iframe>
                </body></html>






          3. See step 13 below to rectify these results









  12. Run grails

    1. grails run-app

      (but something is wrong with the skin...)

    2. additional step (from SmartGWT forum posting) to correct this:

      1. rename grails-app/views/layouts/main.gsp.



    3. grails run-app

      (now it's OK)



  13. The steps above will produce a working example but it produces an empty page as a result!?

    1. Modify src\gwt\client\helloworld.java as below to put a GUI widget into the page (recompile before trying again):





package client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

public class helloworld implements EntryPoint {

public void onModuleLoad() {
final Button button = new Button("Click me");
final Label label = new Label();

button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
if (label.getText().equals(""))
label.setText("Hello World!");
else
label.setText("");
}
});
RootPanel.get("slot1").add(button);
RootPanel.get("slot2").add(label);

}
}

Alternatively, you could put a SmartGWT widget in there instead e.g.



import com.smartgwt.client.util.SC;
...
public void onModuleLoad() {
SC.say("Hello SmartGWT"); // This launches SmartGWT's version of an alert dialogue box
}
// NOTE" No need to add this component to the Root Panel!
}

Next steps:


No comments: