The Source for Java Technology Collaboration
User: Password:



Evan Summers

Evan Summers's Blog

Invetigation in Process 2: Event Pump DTs

Posted by evanx on November 22, 2006 at 02:40 AM | Comments (11)

It is often convenient to execute long tasks synchronously, that is to say, to wait for the task to complete, so that we can then do something appropriate like update the GUI. In order for our GUI to remain responsive while our long task is executing, we can use foxtrot.sf.net which manages to hook into the EventDispatchThread.pumpEvents() method to keep the events rolling.



Salientology

In case you don't want to read Event Pump DTs, a scifi space opera, in all its gory detail, we extract some salient bits and present them below.


Code Glance

We might introduce a doInBackgroundAndWait() method as below.

public class QEdtInvoker {
    ...
    public <T> T doInBackgroundAndWait(final Callable callable) 
    throws Exception {
        final QEventPump eventPump = new QEventPump();
        SwingWorker worker = new SwingWorker() {
            protected Object doInBackground() throws Exception {
                try {
                    return callable.call();
                } finally {
                    eventPump.done();
                }
            }
        };
        worker.execute();
        eventPump.pumpEvents(); 
        try {
            return (T) worker.get();
        } catch (Exception e) {
            throw getActualCause(e);
        }
    }
}

An alternative to actually pumping events is to a use an "invisible" modal Dialog to disable and block our application while executing a "background" task (synchronously).

public class QEventPump {
    protected JDialog dialog;
    
    public QEventPump(JFrame frame) {        
        dialog = new JDialog(frame, true);
        dialog.setUndecorated(true);
        dialog.setBounds(0, 0, 0, 0);
    }
    
    public void pumpEvents() {
        dialog.setVisible(true);
       
    }
    
    public void done() {
       dialog.setVisible(false);
    }    
}

In this case we aren't actually pumping all events on our frame, but are disabling mouse and keyboard events by means of the modal dialog, which invokes the EDT's pumpEventsForHierachy() method.


Demo

The following demo displays an undecorated modal dialog which overlays our status bar (to appear to be our status bar) and displays a progress bar and a cancel button, while blocking our application.

Launch (AddressFormDemo, 150k/500k, unsandboxed, Java6)



Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • When trying to launch the webstart app, I get a java.lang.UnsupportedClassVersionError.

    The jnlp says j2se version="1.5+" and I do have 1.5 installed. Maybe you compiled it for Java 6?

    Posted by: goron on November 22, 2006 at 07:42 AM

  • Yes, it works if I force my runtime to use Java SE 6

    Posted by: goron on November 22, 2006 at 07:45 AM

  • Yes, i'm running/compiling with Netbeans5.5 and Java6 - are you running AddressFormDemo? In the meantime, i'll change the JNLP to 1.6+

    Posted by: evanx on November 22, 2006 at 08:21 AM

  • Tip: if you write GUI logic in JavaScript (JDK 6 Rhino), it is much easier to switch threads "in the middle of" a method body, since you can use continuations to hide the dirty work:

    an old blog entry of mine

    There is no need to insert a nested event queue here; the effect is similar to hand-written Java code which (being rewritten to explicit continuation-passing style) posts chunks of functionality to the EQ and to other threads in order. Of course if you also want to block input then a modal dialog is the simplest approach.

    Posted by: jglick on November 22, 2006 at 12:14 PM

  • Hey Evan,
    I see you are using the Address Book GUI created with GridBagLayout... Have you seen MiG Layout? I think it's a bit cleaner and the example in the wiki is the Address Book GUI..

    http://wiki.java.net/bin/view/Javadesktop/MigLayout

    Cheers,
    MIkael Grev

    Posted by: mikaelgrev on November 22, 2006 at 11:42 PM

  • Howya Mikael! MIgLayout looks great. I've pretty much used Gbc exclusively, without mixing in Flow or Box or Spring or whatever, and i'm a happy Gbc camper. But since GroupLayout is the standard behind Netbeans Matisse, i'm making an effort to move out of my Gbc comfort zone...

    Posted by: evanx on November 23, 2006 at 12:40 AM

  • I welcome you try the warm and fuzzy feeling (almost like love ;) you'll be sure to get when hand coding layouts with MiG Layout. You'll probably get the same feeling doing Visual Layout with the great Matisse.

    In my perfect imaginary world MiG Layout would rule the hand coded segment and Matisse the IDE-layout segment. However, in that world I would also be the one that photographs Bill Gates running Open Office on Linux... ;)

    Cheers,
    Mikael

    Posted by: mikaelgrev on November 23, 2006 at 01:07 AM

  • evanx, pardon the off-topic from a rookie java.net blogger, but how do you pretty-print the code sketches in the blog? Is it something that should be prepared off-line and then cut and copied, or is there any magic HTML tag? :-) Thanks.

    Posted by: fabriziogiudici on November 23, 2006 at 02:32 AM


  • Fabrizio, i'm pleased you asked about that! i still need to write an article about how i write articles! ;) Before i do that, i need to get its quitehyper.dev.java.net project in order. Currently my articles (source) are in there but must move to aptcontent.dev.java.net.

    The short answer is that I write an article in pretty much standard HTML and then run a trivial post-processor on it. The primary purpose of which is to process the Java pre blocks with syntax highlighting. The code is the quitehyper package of aptfoundation.dev.java.net but needs to move to quitehyper project, and be more reusable. Incidently this week i moved other subprojects out of aptfoundation except quitehyper and quitegooey, which i will do over the following week. (Just requires an hour or two of work, when i'm not in the mood to do anything else).

    Also i introduce other conveniences, like blank line means a paragraph break, and also i have special notation for URLs and teletype (using a tilde eg. ~columnCount), as you can see in the "source" for the articles (in quitehyper CVS). Something else i did in quitewriter (quitehyper's predecessor) was to generate table of contents, which you can see in "squashed gooey beans" article on quitegooey.dev.java.net. But i haven't needed that in quitehyper yet, so consequently haven't done it yet.

    There is a simple style template (header-article.html) where i'm starting to put some styles, but otherwise i output them directly using "style" HTML attribute (as you can see in QHyperTextProcessorProperties class)

    There are three "modes" of output that i require. One is an article sitting on java.net CVS, which i've pretty much got right (i mean i'm happy with that). The other is to process HTML for JTextPane in demo applications, which is also OK. The third (which i have been battling with) is to paste into a blog entry. Something with the default CSS makes things go haywire, so now i'm trying to not put any styling into that, which is a pity.

    In the above page for example, i can't use my favourite Verdana font, and New Courier for the preformatted code snippets, and can't control the font sizes, without things going wonky. And that is of course on a live blog article, so not much room to experiment, compared to java.net CVS, where of course one can commit and refresh to kingdom come until the styling works. Incidently, I only test in firefox, but seems to look the same in IE7 when i tried that the other day.

    Depending on which mode, you gotta "preconfigure" the QHyperTextProcessorProperties by using QDependencyContainer to create the properties, eg. for an CVS article we invoke configureArticle() and for HTML to paste into blog entry, configureEmbedded(). Then when QHyperTextProcessor gets this properties instance from the dependency container, it will get the instance that you have customised already.

    As i said, i still need to make the code more reusable, in order to write an article on it. I will try to do this over the next week :)

    Posted by: evanx on November 23, 2006 at 08:59 AM

  • by the way, the source the event pump article is in here
    and the above intro here

    Posted by: evanx on November 23, 2006 at 09:13 AM

  • Thank you, it sounds cool. I'll try it.

    Posted by: fabriziogiudici on November 23, 2006 at 02:31 PM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds