Bitte das folgende Codefragment berücksichtigen:Warten auf mehr SwingWorkers
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();
}
}
}
Hier ist ein Label des Applet hinzuzufügen, dass einige Zwischenergebnisse des Worker-Thread zeigt (mit Publish/Prozessmethoden). Am Ende wird das Label aus dem Applet-Bereich entfernt. Meine Frage ist, wie kann ich mehrere Etiketten erstellen, jeder mit seinem eigenen Worker-Thread, und sie entfernen, wenn sie alle fertig sind?
Vielen Dank im Voraus.
UPDATE:
Ich hoffe, das meine Frage zu klären. Ich möchte, dass die Etiketten auf einmal entfernt werden, wenn alle Arbeiter ihre Arbeit beendet haben, nicht sofort nachdem jeder Arbeiter fertig ist.
UPDATE 2:
Das scheint folgender Code zu tun, was ich brauche. Bitte kommentieren Sie, ob ich es richtig gemacht habe. Ich habe das Gefühl, dass etwas nicht stimmt. Ein Problem besteht darin, dass die Beschriftungen rechts neben der Schaltfläche sichtbar bleiben, obwohl sie entfernt werden. setVisible (false) scheint dieses Problem zu lösen. Ist das der Weg, es zu tun?
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();
}
}
}
}
Sie könnten auch erwägen, sie in einer Liste ('JList') setzen. –
@AndrewThompson, Yep, aber wo sollte ich den Code platzieren, der sie warten wird? Sollte es ein anderer SwingWorker sein, der mehrere andere hervorbringt? – Vlad
Bitte nicht Ausnahmen verschlucken. – trashgod