Hallo, ich möchte gerne eine JProgressBar benutzen um den aktuellen Fortschritt eines Threads anzuzeigen. Ich habe mal ein Tutorial umgeschrieben. Mein Problem ist, dass ich auf das Ende des Threads warten muss, bevor das Programm weiter läuft. In dem Tutorial wird ein SwingWorker genutzt und da gibt es kein .join(), ich habe es mit .get() versucht, aber dann wird die ProgressBar nicht mehr aktuallisiert. Hier mein code:
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
public class ProgressBarDemo extends JPanel
implements ActionListener,
PropertyChangeListener {
private JProgressBar progressBar;
private JButton startButton;
private JTextArea taskOutput;
private Task task;
private boolean done;
class Task extends SwingWorker<Void, Void> {
/*
* Main task. Executed in background thread.
*/
@Override
public Void doInBackground() {
int progress = 0;
setProgress(0);
while (progress <= 1000) {
setProgress( (int)((double)progress/(double)10) );
progress++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
/*
* Executed in event dispatching thread
*/
@Override
public void done() {
done = true;
//Toolkit.getDefaultToolkit().beep();
//startButton.setEnabled(true);
//setCursor(null); //turn off the wait cursor
//taskOutput.append("Done!\n");
System.out.println("done");
}
}
public ProgressBarDemo() {
super(new BorderLayout());
//Create the demo's UI.
startButton = new JButton("Start");
startButton.setActionCommand("start");
startButton.addActionListener(this);
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
taskOutput = new JTextArea(5, 20);
taskOutput.setMargin(new Insets(5,5,5,5));
taskOutput.setEditable(false);
JPanel panel = new JPanel();
panel.add(startButton);
panel.add(progressBar);
add(panel, BorderLayout.PAGE_START);
add(new JScrollPane(taskOutput), BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
}
/**
* Invoked when the user presses the start button.
*/
public void actionPerformed(ActionEvent evt) {
startButton.setEnabled(false);
//setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
//Instances of javax.swing.SwingWorker are not reusuable, so
//we create new instances as needed.
task = new Task();
task.addPropertyChangeListener(this);
task.execute();
while( !task.isDone() ){
}
System.out.println(task.getProgress());
}
/**
* Invoked when task's progress property changes.
*/
public void propertyChange(PropertyChangeEvent evt) {
if ("progress" == evt.getPropertyName()) {
int progress = (Integer) evt.getNewValue();
progressBar.setValue(progress);
progressBar.paint(progressBar.getGraphics());
taskOutput.append(String.format(
"Completed %d%% of task.\n", task.getProgress()));
}
}
/**
* Create the GUI and show it. As with all GUI code, this must run
* on the event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("ProgressBarDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new ProgressBarDemo();
//newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}