FeaturesPluginsDocs & SupportCommunityPartners

Howto use wait and progress cursors

Author: Dafe Simonek
$Revision: 1.5 $
$Date: 2003/01/24 13:36:32 $
Document history: available in CVS

What are wait cursors for

  • they signalize user that application is doing something at this moment
  • they signalize that communication between user and application is stopped or limited for a while
  • they don't tell anything about progress of the work neither they tell if application is totally frozen

When to use wait cursors

Generally, busy cursors should be used rarely, only in specific, special situations. Main reason is that waiting of any kind means discomfort for user, especially if UI is frozen.

  • Busy cursor (usually shown as hourglass or stop-watch) is to be used on component which performs operation that blocks event dispatch thread for at least half of second up to 5-10 seconds max. Especially longer lasting operations should have good reasons to show busy cursor!
  • Wait cursor (combined selection cursor and busy cursor) should be used whenever logic behind the component performs operation in separate thread, so that UI is not blocked. UI component typically shows some status text like "loading". Again, use for tasks that last at least half of second, up to 5-10 seconds ideally. Progress cursor can also be sometimes used for longer lasting tasks, combined with real progress information - status texts, percentage progress indicators.
  • Don't use busy or wait cursors for background tasks that are completely separated, non visible from UI - there won't be a component to set cursor to anyway.
  • Don't use busy or wait cursors for tasks which last longer then 5-10 seconds. Use real progress indicator instead.

API for setting cursors

API is really simple, built in JDK. Consists of methods setCursor, getCursor in class java.awt.Component. JDK support doesn't include wait cursor, that's why Netbeans platform introduced method Utilities.createProgressCursor.

Example use of busy cursor (usually shown as hourglass or stop-watch)

    // code is running in event dispatch thread
    currentComponent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    try {
        // perform some work in event dispatch thread
        // (block UI)
    } finally {
        currentComponent.setCursor(null);
    } 
    

Example use of wait cursor (combined selection cursor and busy cursor)

    // code is running in other then event dispatch thread
    currentComponent.setCursor(Utilities.createProgressCursor(currentComponent));
    try {
        // perform some work in other than event dispatch thread
        // (do not block UI)
    } finally {
        currentComponent.setCursor(null);
    } 
    

Notes:
  • When your component originally had non-default cursor, save this cursor and restore in finally block.
  • Use of try-finally block is important, don't omit it! Such technique will protect us from bugs where wait cursor is set to component forever
  • Remember to set and restore cursors in the same thread in which actual work is performed, to surround working time correctly.

Please send comments to nbdev.

Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Open ESB - The Open Enterprise Service Bus Powered by