Я пытаюсь изучить SwingWorker
, и у меня есть этот простой код, работающий и работающий, но я не могу понять, как вызвать JOptionPane.showMessageDialog
, когда задача будет выполнена. Я должен был попытаться поставитьКак вызвать JOptionPane после завершения задачи SwingWorker
if (isDone())
JOptionPane.showMessageDialog(null, "Task Complete");
в разных местах, но не может заставить ничего работать. Я прочитал, что мне, возможно, придется поместить его в invokeLater()
, чтобы он работал в EDT, я не совсем уверен, как это сделать.
Я пытался использовать мой SwingWorker
в качестве члена класса моей панели, но я не могу его создать, потому что он интенсифицируется в слушателе. Поэтому я получаю нулевой указатель, пытаясь положить if (task.isDone())
в мой invokeLater()
.
Каков правильный способ выполнения этой задачи?
У меня есть SSCCE здесь (все, что вы делаете, это ввести число, и оно печатает мое имя много раз в текстовой области).
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.*;
public class RepeatNameSwingWorker extends JPanel {
private JProgressBar jpb = new JProgressBar(0, 100);
private JTextArea jtaNames = new JTextArea(20, 50);
private final JTextField jtfTimes = new JTextField(8);
private final JButton jbtExecute = new JButton("Execute");
private final JLabel jlblNumTimes = new JLabel("Enter number of times: ");
public RepeatNameSwingWorker(){
jpb.setStringPainted(true);
jtaNames.setLineWrap(true);
jtaNames.setWrapStyleWord(true);
JPanel panel = new JPanel();
panel.add(jlblNumTimes);
panel.add(jtfTimes);
panel.add(jbtExecute);
setLayout(new BorderLayout());
add(jpb, BorderLayout.NORTH);
add(new JScrollPane(jtaNames), BorderLayout.CENTER);
add(panel, BorderLayout.SOUTH);
jbtExecute.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
RepeatNames task = new RepeatNames(
Integer.parseInt(jtfTimes.getText()), jtaNames);
task.addPropertyChangeListener(new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent e) {
if ("progress".equals(e.getPropertyName())) {
jpb.setValue((Integer)e.getNewValue());
}
}
});
task.execute();
if (task.isDone())
JOptionPane.showMessageDialog(null, "Task Complete");
}
});
}
static class RepeatNames extends SwingWorker<String, String>{
int times;
JTextArea result;
public RepeatNames(int times, JTextArea result) {
this.times = times;
this.result = result;
}
@Override
protected String doInBackground(){
publishNames(times);
return null;
}
@Override
protected void done() {
try {
result.append(get().toString()); // Display in text field
} catch (Exception ex) {
result.append(ex.getMessage());
}
}
@Override
protected void process(List<String> list) {
for (int i = 0; i < list.size(); i++) {
result.append(list.get(i) + " ");
}
}
private void publishNames(int n) {
int count = 0;
int number = 2;
while (count <= n) {
if (isPrime(number)) {
count++;
setProgress(100 * count/n);
publish("Paul");
}
number++;
}
}
private static boolean isPrime(int number) {
for (int divisor = 2; divisor <= number/2; divisor++) {
if (number % divisor == 0) {
return false;
}
}
return true;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new RepeatNameSwingWorker());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
});
}
}
Странно, я изначально пробовал это, но это не сработало. теперь он делает :) –