«« Free Software Realities Let's Talk About the "I" Word: Innovation »»
blog header image
Roll Your Own ApplicationWindow OnOpenListener

JFace's ApplicationWindow object doesn't seem to have a listener that is triggered when it is opened. This is unfortunate because there are lots of things that you might want to do when the "UI is ready", like load it with data.

Warning, the following explanation is from 30,000 feet ...

ApplicationWindow uses the method open() to show itself. Developers usually make this method call block, meaning that code after open() doesn't execute until after the window is closed. After open(), everything is event-driven. So you can't make a call to your database after open() and expect it to affect the GUI. There is a way to get around it though.

The windowing toolkit that JFace uses, SWT, is a layer on top of each operating system it is written to. SWT receives messages from the operating system and stuffs them into a queue. These are messages about if the mouse pointer moved, if a click happened or if a letter was typed. SWT then processes these events and updates the application's GUI.

Do you remember me blogging about asyncExec()? This method call just puts a Runnable on SWT's queue, usually from a non-UI thread because SWT only allows the SWT thread to modify it. But who says you can't use it from the UI thread too? Here's how I did it:

public static void main(String[] args)
   ApplicationWindowSubclass window = new ApplicationWindowSubclass();

   window.getShell().getDisplay().asyncExec(new Runnable()
      public void run()
         //do your task in here



Now the task runs right after the window appears. The trick is window.create(). Usually you don't have to call it but it will initialize the Shell for you (I found that out poking around in the SWT code). Otherwise the Shell is null until open() (too late!). Without window.create(), you can't getDisplay() from the window's Shell and you can't use asyncExec().

BTW, I used this technique to put progress bars in AudioMan when it loads and saves the repository on open and exit. It looks sweet! I'll be releasing a new version of AudioMan (0.3.1) shortly.

Posted at March 01, 2004 at 07:34 AM EST
Last updated March 01, 2004 at 07:34 AM EST

Why not just use Display.getDefault() to get dislpay object? I'm so interested in that subject since I'm running into same problems right now :(

» Posted by: Ali Zaid at March 1, 2004 09:58 PM

Hey! That works. I tried getCurrent() with no window.create() and I got NullPointerException .... but getDefault() works.

» Posted by: Ryan at March 1, 2004 11:42 PM

Either way you still have to queue the event you want to have after open() this way because open() blocks.

» Posted by: Ryan at March 1, 2004 11:46 PM

Well, I have to thank you allot, you saved my day, I finally solved my problem because of you wonderful articals...

I had this killing thread that select from a database about 59721 Record, I have to show 1000 one in each page, still, I have no control over which (not serial), even with filters I couldn't have my gui running right, I knew about asyncExec but I did not know how to use it.

I'm so Thankful

» Posted by: Ali Zaid at March 2, 2004 02:32 PM
Search scope: Web ryanlowe.ca