Duane Allman
Duane Allman

Reputation: 571

JInternalFrame won't appear

I have a java class called GameUpdater which extends JInternalFrame. It used to extend JFrame when I ran the class as a program by itself, but I changed it to JInternalFrame to become part of a larger application - now accessible from a menu button.

The function being called when I press this menu button is as follows:

private void update(){

    GameUpdater gu = new GameUpdater();
    desktop.add(gu); //add to JDesktopPane
    gu.setSize(400, 300);
    gu.setVisible(true);

    gu.readMatches();//this function takes ages

    gu.setMatch("Updating database...");//this is some output to the user, displays info in the internal frame
    //try and insert into database
    for(Match m : gu.getMatches()){
        db.insertMatch(m);
    }
    gu.setMatch("DONE"); //now it shows the frame, way too late
}

The method gu.readMatches() takes a long time to execute, so it periodically updates content in the JInternalFrame to display its progress. However the frame is not being shown until this update function is complete!

It's like setVisible(true) is waiting until the end of the function...

It worked absolutely fine when it was a JFrame. Is there any weird property of a JInternalFrame that would cause this?

Cheers

Upvotes: 1

Views: 269

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347334

It sounds like you're executing a time consuming process inside the Event Dispatching Thread (EDT), this will prevent the event queue from process (amongst other things) repaint requests.

This will cause you program to appear as if it has "hung".

You need to off load this task to a background thread.

Have a read through Concurrency in Swing, especially the section on Worker Threads and SwingWorker

Upvotes: 2

David Kroukamp
David Kroukamp

Reputation: 36423

The problem is that you are blocking your EDT this can be taken care of by simply creating a new Thread/Runnable thar calls gu.readMatches(); the method:

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
gu.readMatches(); //gu will have to be declared `final`

gu.setMatch("Updating database...");//this is some output to the user, displays info in the internal frame
//try and insert into database
for(Match m : gu.getMatches()){
    db.insertMatch(m);
}
}
});

ofcourse though you might want to implement a JProgressBar so the user can keep track of of how far the reading is.

Upvotes: 2

Related Questions