tags:

views:

89

answers:

3

Hello All,

I'm trying to use threads to run a lenghty operation in the background and update the UI. Here's what i'm trying to do:

  1. on a button click, display a popupjframe with a message "Inserting into DB"
  2. create a new thread to insert 1000s of entries into a database.
  3. when the entries are inserted, i want the popupjframe to disappear and display a joptionpane with yes, no buttons
  4. on clicking the yes button i want to display another frame with a report/details about the insertion process

Here's my code:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//display popupframe first

jFrame1.pack();
jFrame1.setVisible(true);
jFrame1.setLocationRelativeTo(getFrame());
Thread queryThread = new Thread() {
public void run() {
runQueries();
}};
queryThread.start();
}

//runqueries method inserts into DB

private void runQueries() {
for (int i = 0; i <= 50000; i++) {
insertintoDB();
updateProgress(i);
}
}

//update the popupjframe
private void updateProgress(final int queryNo) {
SwingUtilities.invokeLater(new Runnable() {
 public void run() {
if (queryNo == 50000) { //means insertion is done
jFrame1.setVisible(false);

int n = JOptionPane.showConfirmDialog(getFrame(), menuBar, null, JOptionPane.YES_NO_OPTION);

if (n == 1) { //NO option was selected
return;}
else
//display another popupframe with details/report of inserting process
}});
}
  1. Is my approach correct??
  2. How and when do i stop/interrupt the "queryThread"??
  3. Is it correct if i make the popupjframe in the runqueries method itself (after the for loop) and display the joptionpane??

Thanks in advance.

+4  A: 

Look at the documentation for SwingWorker. It does exactly what you are trying to do. Create a subclass, and call runQueries from doInBackground(), and then do what your runnable does (minus the if queryNo check) in done(). There are third party versions of this class if you are not using java 1.6.

class DbSwingWorker extends SwingWorker<Void, Integer> {

    @Override
    protected Void doInBackground() throws Exception {
        for (int i = 0; i <= 50000; i++) {
            insertintoDB();
            publish(i); //if you want to do some sort of progress update
        }
        return null;
    }

    @Override
    protected void done() {
        int n = JOptionPane.showConfirmDialog(getFrame(), menuBar, null, JOptionPane.YES_NO_OPTION);

        if (n == 1) { //NO option was selected
            return;
        } else {
            //display another popupframe with details/report of inserting process

        }
    }
}

The original, non-1.6 version can be found here: https://swingworker.dev.java.net/

ILMTitan
Also see <http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html>.
Steve Emmerson
A: 

@Java Drinker: Yep, that is what i thought too, that it's a ridiculous load on the app....but I didn't know a workaround until now...

@ILMTitan: Thanks a ton!! works like a charm..Do you know any good third party classes?? (in case i don't want to use java 1.6)

@Emmerson: Thanks for the link

Fishinastorm
@Fishinastorm: Please consider accepting (green check) and/or up-voting (gray triangle) answers that you found helpful.
trashgod
A: 

guys...am running into a small problem while trying to cancel the worker...

  1. Clicking a button displays a popupframe with a table. Loading the table data is done in a worker thread.
  2. The popupframe also has a cancel button which i want to use to cancel the worker thread.

The problem is that when i try to cancel the worker by pressing the cancel button, the worker continues to execute. Any idea??

Below is my code:

private SwingWorker<Void,Object[]> metaworker=null;
private void butMetadataActionPerformed(java.awt.event.ActionEvent evt) {  
//display popupframe
metaworker = new SwingWorker<Void,Object[]>() {
@Override
protected Void doInBackground() throws Exception {
if (!isCancelled()) {
Object[] metadataRsts=null;

//do some work

publish(metadataRsts); } return null;}

@Override
protected void process(List<Object[]> chunks) {
for (Object[] row : chunks) {
((DefaultTableModel) tblMetadata.getModel()).addRow(row);
}}};
metaworker.execute();
}// end button action event

//button in the popup frame which should cancel the worker
private void butCancel2ActionPerformed(java.awt.event.ActionEvent evt) { 
metaworker.cancel(true);
}

Thanks once again.

fishinastorm