How can I know where all the threads are finished? If I use a counter
inside invokeLater I think I will I run into race conditions..
- not possible because this is endless loop without
break;
So what is the right way to do it?
JProgressBar has range from zero to 100 in API, just to test if value in loop is 100 or greather, then to use break;
use Runnable#Thread instead of plain vanilla Thread
for example (the same output should be from SwingWorker, but there are is used more than 12 instances, AFAIK note there was a bug about overloading number of..., but for purpose as code for forum is possible to create similair code by using SwingWorker)



import java.awt.Component;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
public class TableWithProgressBars {
private static final int maximum = 100;
private JFrame frame = new JFrame("Progressing");
Integer[] oneRow = {0, 0, 0, 0};
private String[] headers = {"One", "Two", "Three", "Four"};
private Integer[][] data = {oneRow, oneRow, oneRow, oneRow, oneRow,};
private DefaultTableModel model = new DefaultTableModel(data, headers);
private JTable table = new JTable(model);
public TableWithProgressBars() {
table.setDefaultRenderer(Object.class, new ProgressRenderer(0, maximum));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
Object waiter = new Object();
synchronized (waiter) {
int rows = model.getRowCount();
int columns = model.getColumnCount();
Random random = new Random(System.currentTimeMillis());
boolean done = false;
while (!done) {
int row = random.nextInt(rows);
int column = random.nextInt(columns);
Integer value = (Integer) model.getValueAt(row, column);
value++;
if (value <= maximum) {
model.setValueAt(value, row, column);
// model.setValueAt(... must be wrapped into invokeLater()
// for production code, otherwise nothing will be repainted
// interesting bug or feature in Java7 051, looks like as
// returns some EDT features from Java6 back to Java7 ???
try {
waiter.wait(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
done = true;
for (row = 0; row < rows; row++) {
for (column = 0; column < columns; column++) {
if (!model.getValueAt(row, column).equals(maximum)) {
done = false;
break;
}
}
if (!done) {
break;
}
}
}
frame.setTitle("All work done");
}
}
}).start();
}
private class ProgressRenderer extends JProgressBar implements TableCellRenderer {
private static final long serialVersionUID = 1L;
public ProgressRenderer(int min, int max) {
super(min, max);
this.setStringPainted(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
this.setValue((Integer) value);
return this;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TableWithProgressBars();
}
});
}
}