Nathan
Nathan

Reputation: 266

Can you progressively update a JPanel through the EventQueue?

I have a log on screen that requires three connections to be set up. Each time a connection is successfully set up I immediately want a buffered image to appear next to it (tick or cross).

At the moment, the images will not appear until the main thread has finished and all three connections are set up. I have tried spawning new threads to deal with the separate connections being set up to see if this may help but it hasn't.

Loading an image (same for cross):

 // Create new JLabel to hold images; stored as a field
    picLabelDataMapper = new JLabel();

 try {
        logger.debug("Reading tick.png image");
        tick = ImageIO.read(new File("tick.png")); // Global Field
    } catch (IOException e) {
        // TODO Auto-generated catch block
        logger.debug("Read tick.png failed");
        e.printStackTrace();
    } 

    // Ensure label is not visible; nothing is loaded at this moment anyway
    picLabelDataMapper.setVisible(false);
    // Add label to panel
    panelDataMapper.add(picLabelDataMapper, "cell 3 1");

Check to see if database was set up successfully:

/**
 * Ensure the data Mapper database was set up successfully
 */
public void checkForDataMapperCompletion(){

    if(dataMapperPassed){

        picLabelDataMapper.setIcon(new ImageIcon(tick));
        picLabelDataMapper.setVisible(true);

    }else{
        picLabelDataMapper.setIcon(new ImageIcon(cross));
        picLabelDataMapper.setVisible(true);
    }
}

So whats the best way to perform a sequential update like this:

Database 1 Set Up > Update GUI

Database 2 Set Up > Update GUI

Database 3 Set Up > Update GUI

Any directions/avenues anyone could recommend to explore ? Thanks in advance.

Upvotes: 2

Views: 66

Answers (1)

Michael
Michael

Reputation: 2726

Putting your database calls on a separate thread puts you on the right track. However, to update the GUI after each thread completes you need to put the GUI update into a Runnable then call SwingUtilities.invokeLater(Runnable).

Here is a rough pseudo-ish example:

public void hitDatabase() {
    Thread thread = new Thread(new DatabaseHelper());
    thread.start();
}

private static class DatabaseHelper implements Runnable {
    public void run() {
        //Hit the DB here
        codeToHitDB();

        //Once Complete update the GUI
        Runnable runnable = new Runnable() {
            public void run() {
                //Update your GUI
            }
        };

        SwingUtilities.invokeLater(runnable);
    }
}

This tutorial will give you more info: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/

There is also a SwingWorker class that some people claim makes this easier. There are details about SwingWorker in the tutorial.

Upvotes: 2

Related Questions