Wednesday, May 20, 2009

Observer Pattern using Closures

I have been working on a small Swing application. Its purpose is a batch download of various items that you select in the GUI. I only discovered Griffon after i had already begun and since it is just one screen, i decided to stay away from it for now. So, once i had the UI built (quite painful as it was a first foray into Swing for me, but that is Java's fault and not Groovy. Perhaps more on that in a separate post) and it was time to launch a thread and get updates from the thread to put in the text box in my application. In Java 6 there is a new class, SwingWorker to deal with this in an elegant way (see here for a demo of how to use it). However, with no inner classes in Groovy, this did not seem like it would work. But, in essence the closure has the power of the inner class since it has access to all the members of the class, so this seemed like way to go. And here it is

So, my worker class has the following:

private List closureList = []

public void addObserver(Closure c) {
    closureList += c
}

public void removeObserver(Closure c) {
   closureList -= c;
}

private void notifyObservers(String fileName, DownloadStatus status) {
   for (c in closureList) {
      c.call(itemName status)
   }
}


and the GUI class has following closure defined.

def guiUpdater = {String filename, DownloadStatus status ->
    swing.edt {
       if (status == DownloadStatus.COMPLETE) {
         resultsTextArea.append("Download of ${filename} completed\n")
       }
    }
}

Notice how in my closure i still need to use the swing event dispatch closure for the updates.

2 comments:

  1. It would be nice if you had code formatting. Keep the posts coming!

    ReplyDelete
  2. Ok, will try for next time. Until i started this did not realize what a nightmare the indentation would be to make, but at least I got that part. But now i see there are some good tools for this

    ReplyDelete