IzPack 4.3.1 is available

June 17th, 2009

I’m pleased to let the world know of the availability of IzPack 4.3.1 :-)

This is a maintenance release. While it is not very spectacular by itself, upgrading is still a very good idea as you will grab a few fixes there and there.

Many thanks to our community (developers, contributors, issue reporters and users) for making this release possible, and go to http://izpack.org to get your copy today!

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • description
  • Live
  • Netvibes
  • StumbleUpon
  • Technorati
  • TwitThis
Author: jponge Categories: English, IzPack, Java Tags:

Support the IzPack development by making a donation!

June 11th, 2009

Hi everyone,

As you can easily guess, maintaining and developing IzPack since 2001 has been a lot of fun… and also a significant time investment :-)

I am already offering professional services for those who would need support, consulting and custom developments (see http://izpack.proservices.ponge.info/). A few companies also give back to the project in the form of patches and contributors / developers: thanks to you all!

However, the large majority of IzPack users simply download it and never give back anything. This is perfectly fine of course, but I would like to let you know that you can support my very own work on this project by making a donation :-)

To do that, you can use the following link (note that you will receive both my gratitude AND a true invoice).


Thanks for your support!

(ps: for those who may ask, the adsense units on the website mainly cover the domain name and web hosting)

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • description
  • Live
  • Netvibes
  • StumbleUpon
  • Technorati
  • TwitThis
Author: jponge Categories: English, IzPack Tags:

Discovering Grails Web Flows

June 1st, 2009

I recently discovered Grails Web Flows. This is basically a Groovy DSL on top of Spring Web Flows.

I did a quick dirty and imperfect example which is a number guessing game. I took inspiration from another Grails Web Flows tutorial.

In this post, I will limit myself to some very quick description of web flows, and I urge you to read the documentations (from Grails and Spring). The idea behind web flows is to provide a framework for web conversations that span multiple HTTP requests, such as wizards, payment processes and such. A “web flow” is modeled as a state machine, where:

  • states represent either an action (i.e., some code) or a view, and
  • transitions are triggered based on the outcome from the state, which is a simple string.

As such, web flows free the developer from much repetitive logic when you need to control states of a web conversation.

In this example, the number to guess is 25 (we could have made it non-static, but who cares?). The user has 5 attempts. The corresponding flow is:

flow

Grails provides web flows out of the box. All you have to do is to create a special controller closure property which ends by “Flow“:

class GuessController
{
 
  def toGuess = "25"
 
  def index = {
    redirect(action: "guess")
  }
 
  def guessFlow = { ... }
 
}

We now have to define the “guess” flow. As often in Groovy and Grails, it boils down to some intuitive builder structure:

class GuessController
{
 
  def toGuess = "25"
 
  def index = {
    redirect(action: "guess")
  }
 
  def guessFlow = {
 
    start {
      action {
        [guessLeft: 5]
      }
      on("success").to("ask")
    }
 
    ask {
      on("evaluate").to("evaluate")
    }
 
    done()
 
    fail()
 
    evaluate {
      action {
        if (params.number == toGuess)
        {
          return yes()
        }
        flow.guessLeft = flow.guessLeft - 1
        if (flow.guessLeft == 0)
        {
          return loose()
        }
        else
        {
          return no()
        }
      }
      on("yes").to("done")
      on("no").to("ask")
      on("loose").to("fail")
    }
  }
}
  1. start is an action state, which is called first, and that puts a guessLeft variable in the flow context.
  2. The ask state displays a web page, then delegates the logic to the evaluate action state.
  3. The evaluate action state either pushes the flow to the final states, or loops back to the ask state if there are guesses left.
  4. done and fail are final states that just show some web pages.

Finally there are 3 views that you need to create. Since the web flow is named “guess”, they must be in a special “guess” subfolder of the matching controller views. Also, they must be named by the state names.

ask.gsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head><title>Simple GSP page</title></head>
  <body>
 
  <g:javascript library="prototype"/>
  <g:javascript>
    document.observe("dom:loaded", function() {
      $("field").focus();  
    });
  </g:javascript>
 
  <h1>Guess</h1>
  <p>Guesses left: <strong>${guessLeft}</strong>.</p>
 
  <p>
    <g:form action="guess">
      <g:textField id="field" name="number" value="0" />
      <g:submitButton name="evaluate" value="Try this number!" />
    </g:form>
  </p>
 
  </body>
</html>

Note that the guessLeft flow context variable is available directly in the GSP. Also, note that the form action must match the web flow name and that the submit button name is the outcome of the view state.

done.gsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head><title>Simple GSP page</title></head>
  <body>You won!</body>
</html>

fail.gsp

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head><title>Simple GSP page</title></head>
  <body>You failed...</body>
</html>
Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • description
  • Live
  • Netvibes
  • StumbleUpon
  • Technorati
  • TwitThis
Author: jponge Categories: English, Geeking, Groovy, Java, Web Tags:

Taking SWT/Cocoa and MigLayout for a spin

May 23rd, 2009

It’s been a while since I last had a look at SWT (the so-called “standard widget tookit”). One very good reason is probably the fact that I have switched to Mac OS X, and the Mac SWT port used to suck badly. To convince yourself, download Eclipse and play with it. I’m sure you’ll feel that it does not really look like a true Mac OS X application, and you will easily spot UI glitches there and there (tip: edit a field in a table, just for fun). This is even more critical when Swing applications like IntelliJ IDEA or Netbeans look so great while relying on a non-native toolkit…

SWT is still a very capable GUI toolkit. Although the API feels a lot more low-level than Swing, you can get some satisfying rsults by using it. It is not a Filthy Rich Clients compatible toolkit (forget the slick interfaces that you can make on top of Swing), but some stuff can become way easier in the world of SWT than in the world of Swing (e.g., embedding a web browser or getting a truly native file dialog). Another good reason for keeping SWT under the radar is that it is actively developed while one can reasonably fear that Swing is… more in a kind of maintenance mode to say the least.

The SWT team recently took the Mac OS X matters seriously and decided to port it over Cocoa, the framework upon which true Mac OS X applications should be built. Indeed, the existing port used to be made over Carbon, the now deprecated Mac APIs that endanger the future of Eclipse on Mac OS X. Although this is still work in progress, SWT/Cocoa is just great (and Eclipse is probably going to look ok on a Mac, although I am not going to switch back to it any time soon).

I took it for a spin to build a very stupid application:

swtapp

If you press the button, a message box shows up to repeat the informations. It also features a label with an hyperlink that pops up a web browser.

Good layouts are both critical (otherwise your application looks like a toy) and hard to realize. I used the fantastic MigLayout libary. There is a version for both Swing and SWT. It is somehow reminiscent of the JGoodies layouts, and the extra bonus is that the library weights really nothing.

My main class is fairly standard for a SWT application:

public class Main
{
    public static void main(String[] args)
    {
        Display display = new Display();
        Shell shell = new Shell(display, SWT.SHELL_TRIM);
        shell.setText("Swt/Cocoa");
 
        new MyController(shell);
 
        shell.pack();
        shell.open();
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
            {
                display.sleep();
            }
        }
 
        display.dispose();
    }
}

My “controller” (which should have not be named like that since it is not a true controller…) is relatively simple too:

public class MyController
{
    private final Shell shell;
 
    public MyController(Shell shell)
    {
        this.shell = shell;
        initialize();
    }
 
    private void initialize()
    {
        final MigLayout layout = new MigLayout("fillx", "[right] rel [grow, fill]");
        shell.setLayout(layout);
 
        final Label nameLabel = new Label(shell, SWT.NONE);
        nameLabel.setText("Name:");
 
        final Text nameText = new Text(shell, SWT.SINGLE | SWT.BORDER);
        nameText.setText("Somebody");
        nameText.setLayoutData("wrap, width 300px");
 
        final Label emailLabel = new Label(shell, SWT.NONE);
        emailLabel.setText("Email:");
 
        final Text emailText = new Text(shell, SWT.SINGLE | SWT.BORDER);
        emailText.setText("foo@bar.com");
        emailText.setLayoutData("wrap");
 
        final Button displayButton = new Button(shell, SWT.PUSH);
        displayButton.setText("Display");
        displayButton.setLayoutData("span 2, tag ok, gapy unrelated, wrap");
 
        final Link urlLink = new Link(shell, SWT.NONE);
        urlLink.setText("<a>More informations...</a>");
        urlLink.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent selectionEvent)
            {
                Program.launch("http://jpz-log.info/");
            }
        });
        urlLink.setLayoutData("span 2, align left, gapy unrelated, wrap");
 
        shell.setDefaultButton(displayButton);
 
        displayButton.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent selectionEvent)
            {
                String normalForm = new StringBuilder()
                        .append(nameText.getText())
                        .append(" <")
                        .append(emailText.getText())
                        .append(">")
                        .toString();
 
                MessageBox box = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
                box.setMessage(normalForm);
                box.open();
            }
        });
    }
}

Simple isn’t it? :-)

Of course it could have been made even more compact by using Groovy, Scala or JRuby…

One last thing: SWT applications need a special -XstartOnFirstThread JVM flag on Mac OS X.

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • description
  • Live
  • Netvibes
  • StumbleUpon
  • Technorati
  • TwitThis
Author: jponge Categories: English, Geeking, IzPack, Java Tags:

Two IzPack use cases (Terracotta and Sun Grid Engine)

May 17th, 2009

I recently became aware of two new great use cases of IzPack. I thought I would share them with you :-)

The first one is brought by Terracotta, the JVM clustering specialists. Download the cross-platform installer and you will get a nicely done IzPack-based installer.

The second one if from the friends at Sun Microsystems, as they built an impressive installer for Sun Grid Engine. That’s a truly awesome one, as it exhibits lots of customizations (e.g., custom panels).

Here are some screenshots (the Sun Grid Engine ones come from their wiki site):

Shall need be, it proves once again that highly specific needs can be served with IzPack, an open and extensible platform for making cross-platform installers. With IzPack you are not constrained within the bounds of a rigid, so classical type of installer framework (I won’t give names, but hey, there is even an installers company that tries to pretend making opensource!).

On a final note, do not forget that you can get IzPack consulting, support and custom development from me :-)

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • description
  • Live
  • Netvibes
  • StumbleUpon
  • Technorati
  • TwitThis
Author: jponge Categories: English, IzPack, Java Tags: