Search code examples
javamultithreadingswingdelay

Java Swing redraw delay


I'm writing a little private application at the moment which utilizes the Wolfram Alpha Java Bindings. The application's GUI is realized using Swing. My Wolfram Alpha Plugin has a function looking like this:

public void fire(String value) {

    // This sets the field state to loading
    _state = loading;

    // This tells the controller to redraw the window
    // When reading the state of the plugin it sets an
    // animated gif at a JPanel. This should be displayed
    // before the application is blocked by the Wolfram Alpha
    // Request. 

    // updateInput does nothing more then call repaint after some
    // other function calls. No special threading included. 

    getController().updateInput("");


    // My wolfram request follows:

    WAQuery query = _engine.createQuery();
    query.setInput(value);
    try {
        // For educational purposes, print out the URL we are about to send:
        System.out.println("Query URL:");
        System.out.println(_engine.toURL(query));
        System.out.println("");

        // This sends the URL to the Wolfram|Alpha server, gets the XML result
        // and parses it into an object hierarchy held by the WAQueryResult object.
        WAQueryResult queryResult = _engine.performQuery(query);

        if (queryResult.isError()) {
            System.out.println("Query error");
            System.out.println("  error code: " + queryResult.getErrorCode());
            System.out.println("  error message: " + queryResult.getErrorMessage());
        } else if (!queryResult.isSuccess()) {
            System.out.println("Query was not understood; no results available.");
        } else {
            // Got a result.
            System.out.println("Successful query. Pods follow:\n");
            for (WAPod pod : queryResult.getPods()) {
                if (!pod.isError()) {
                    System.out.println(pod.getTitle());
                    System.out.println("------------");
                    for (WASubpod subpod : pod.getSubpods()) {
                        for (Object element : subpod.getContents()) {
                            if (element instanceof WAPlainText) {
                                System.out.println(((WAPlainText) element).getText());
                                System.out.println("");
                            }
                        }
                    }
                    System.out.println("");
                }
            }
            // We ignored many other types of Wolfram|Alpha output, such as warnings, assumptions, etc.
            // These can be obtained by methods of WAQueryResult or objects deeper in the hierarchy.
        }
    } catch (WAException e) {
        e.printStackTrace();
    }


}

The Problem is that the request is started BEFORE the window is repainted. I have a request delay of about one second and THEN the loading animation is displayed. This animation should be displayed before the request is started.

What I tried so far:

  • Thread.sleep() in front of the Wolfram Query. But that would block the repaint too?! - same unwanted behavior
  • Put the request into a runnable - same unwanted behavior
  • Put the request into a class extended by Thread - same unwanted behavior
  • Combine both with Thread.sleep() - same unwanted behavior

What am I overseeing here?


Solution

  • I have a request delay of about one second and THEN the loading animation is displayed. This animation should be displayed before the request is started.

    Never use Thread.sleep() in Swing application that sometime hangs the whole application as you stated it already in your post. You should use Swing Timer in that case.

    Please have a look at How to Use Swing Timers

    Sample code:

    Timer timer = new Timer(1000, new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent arg0) {            
            // start loading animation now
        }
    });
    timer.setRepeats(false);
    timer.start()