Please consider the following code fragment:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class TestApplet extends JApplet
{
@Override
public void init()
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
createGUI();
}
});
}
catch(InterruptedException | InvocationTargetException ex)
{
}
}
private void createGUI()
{
getContentPane().setLayout(new FlowLayout());
JButton startButton = new JButton("Do work");
startButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
JLabel label = new JLabel();
new Worker(label).execute();
}
});
getContentPane().add(startButton);
}
private class Worker extends SwingWorker<Void, Void>
{
JLabel label;
public Worker(JLabel label)
{
this.label = label;
}
@Override
protected Void doInBackground() throws Exception
{
// do work
return null;
}
@Override
protected void done()
{
getContentPane().remove(label);
getContentPane().revalidate();
}
}
}
Here is add a label to the applet that displays some intermediate results of the Worker thread (using publish/process methods). At the end, the label is removed from the applet's pane. My question is, how could I create several labels, each with its own Worker thread, and remove them when they are all done?
Thanks in advance.
UPDATE:
I hope this will clarify my question. I'd like the labels to be removed all at once, when all of the workers have finished their tasks, not immediately after each worker has finished.
UPDATE 2:
The following code seems to be doing what I need. Please comment whether I did it the right way. I have a feeling there is something wrong. One problem is that the labels to the right of the button remain visible although they are removed. setVisible(false) seems to solve this issue. Is that the way to do it?
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.*;
public class TestApplet extends JApplet
{
private Queue<JLabel> labels = new LinkedList<>();
private static final Random rand = new Random();
@Override
public void init()
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
createGUI();
}
});
}
catch(InterruptedException | InvocationTargetException ex){}
}
private void createGUI()
{
getContentPane().setLayout(new FlowLayout());
JButton startButton = new JButton("Do work");
startButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
ExecutorService executor = Executors.newFixedThreadPool(10);
for(int i = 0; i < 10; i++)
{
JLabel label = new JLabel();
getContentPane().add(label);
executor.execute(new Counter(label));
}
}
});
getContentPane().add(startButton);
}
private class Counter extends SwingWorker<Void, Integer>
{
private JLabel label;
public Counter(JLabel label)
{
this.label = label;
}
@Override
protected Void doInBackground() throws Exception
{
for(int i = 1; i <= 100; i++)
{
publish(i);
Thread.sleep(rand.nextInt(80));
}
return null;
}
@Override
protected void process(List<Integer> values)
{
label.setText(values.get(values.size() - 1).toString());
}
@Override
protected void done()
{
labels.add(label);
if(labels.size() == 10)
{
while(!labels.isEmpty())
getContentPane().remove(labels.poll());
getContentPane().revalidate();
}
}
}
}
JList
). – Archerfish