0

I have a JNI function that can take a while to complete, and I want a JProgress bar in indeterminate mode running while it is finishing the function. I have read the tutorials provided by Oracle, but the nature of their tutorials doesn't seem to help me understand how to do it. I realize that I should be running this function in a background thread, but I'm not quite sure how to do it.

Here is relevant code. I have a button (runButton) that will call the function, mainCpp(), when pressed:

public class Foo extends javax.swing.JFrame 
                         implements ActionListener,
                                    PropertyChangeListener{

    @Override
    public void actionPerformed(ActionEvent ae){
        //Don't know what goes here, I don't think it is necessary though because I do not intend to use a determinate progress bar
    }

    @Override
    public void propertyChange(PropertyChangeEvent pce){
        //I don't intend on using an determinate progress bar, so I also do not think this is necassary
    }

class Task extends SwingWorker<Void, Void>{

    @Override
    public Void doInBackground{
         Foo t = new Foo();
         t.mainCpp();

         System.out.println("Done...");
    }
    return null;
}

/*JNI Function Declaration*/
public native int mainCpp(); //The original function takes arguments, but I have ommitted them for simplicity. If they are part of the problem, I can put them back in.

...//some codes about GUI

private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {

    ProgressBar.setIndeterminate(true);
    Task task = new Task();
    task.execute();    
    ProgressBar.setIndeterminate(false);

}


/*Declarations*/
private javax.swing.JButton runButton;
}

Any help would be appreciated.

EDIT: Editted in an attempt to do what kiheru suggested, but still does not work.

Sean Sen Wang
  • 193
  • 1
  • 1
  • 12
  • Your assumption about running it in doInBackround() is correct. SwindWorkers just need an `execute()` call to start running, so if you prepare the worker in advance you can just call that in the button action. Alternatively you can create a SwingWorker in place, and execute that. – kiheru Aug 06 '13 at 19:04
  • Can you elaborate on what you mean to "prepare the worker in advance"? – Sean Sen Wang Aug 06 '13 at 19:06

1 Answers1

0

Assuming you have a SwingWorker like this:

class Task extends SwingWorker<Void, Void>{
    @Override
    public Void doInBackground() {
        // I'm not sure of the code snippets if you are already in a
        // Foo instance; if this is internal to Foo then you obviously do
        // not need to create another instance, but just call mainCpp().
        Foo t = new Foo();
        t.mainCpp();
        return null;
    }

    @Override
    public void done()
        // Stop progress bar, etc
        ...
    }
}

You can either keep an instance in a field of the containing object, and then using it would work like this:

private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {
    // Start progress bar, disable the button, etc.
    ...
    // Task task has been created earlier, maybe in the constructor 
    task.execute();
}

, or you can create a worker in place:

private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {
    // Start progress bar, disable the button, etc.
    ...
    new Task().execute();
}
kiheru
  • 6,588
  • 25
  • 31
  • I believe this is what I attempted (check my edit), but the Progress Bar does not move. – Sean Sen Wang Aug 06 '13 at 19:26
  • @SeanSenWang Don't stop the progress bar in runButtonActionPerformed() - that will be done immediately. Instead do it in `done()` of the SwingWorker. Also note the comment about `new Foo()` (should not break anything, but may be unneeded) – kiheru Aug 06 '13 at 19:33
  • Ah, I need to set `indeterminate(false)` outside of the action event. Thank you very mnuch! – Sean Sen Wang Aug 06 '13 at 19:36