JProgress Bar Неопределенный режим не обновляется

У меня есть функция JNI, выполнение которой может занять некоторое время, и я хочу, чтобы панель JProgress работала в неопределенном режиме, пока она завершает выполнение функции. Я прочитал учебные пособия, предоставленные Oracle, но характер их учебных пособий, похоже, не помогает мне понять, как это сделать. Я понимаю, что мне следует запускать эту функцию в фоновом потоке, но я не совсем уверен, как это сделать.

Вот соответствующий код. У меня есть кнопка (runButton), которая при нажатии вызывает функцию mainCpp():

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;
}

Любая помощь будет оценена по достоинству.

EDIT: отредактировано в попытке сделать то, что предложил kiheru, но все еще не работает.


person Sean Sen Wang    schedule 06.08.2013    source источник
comment
Ваше предположение о его запуске в doInBackround() верное. SwindWorkers просто нужен вызов execute(), чтобы начать работу, поэтому, если вы заранее подготовите работника, вы можете просто вызвать его в действии кнопки. В качестве альтернативы вы можете создать SwingWorker на месте и выполнить его.   -  person kiheru    schedule 06.08.2013
comment
Не могли бы вы уточнить, что вы имеете в виду под подготовкой работника заранее?   -  person Sean Sen Wang    schedule 06.08.2013


Ответы (1)


Предполагая, что у вас есть SwingWorker, подобный этому:

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
        ...
    }
}

Вы можете либо сохранить экземпляр в поле содержащего объекта, и тогда его использование будет работать следующим образом:

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();
}

, или вы можете создать рабочего на месте:

private void runButtonActionPerformed(java.awt.event.ActionEvent evt) {
    // Start progress bar, disable the button, etc.
    ...
    new Task().execute();
}
person kiheru    schedule 06.08.2013
comment
Я считаю, что это то, что я пытался (проверьте мое редактирование), но индикатор выполнения не перемещается. - person Sean Sen Wang; 06.08.2013
comment
@SeanSenWang Не останавливайте индикатор выполнения в runButtonActionPerformed() - это будет сделано немедленно. Вместо этого сделайте это в done() SwingWorker. Также обратите внимание на комментарий о new Foo() (ничего не должно ломаться, но может быть ненужным) - person kiheru; 06.08.2013
comment
Ах, мне нужно установить indeterminate(false) вне события действия. Большое спасибо! - person Sean Sen Wang; 06.08.2013