Temat: SwingWorker. Problem z zastosowaniem
Wiesław Kurko:
- klasa generująca całkowite liczby losowe z konkretnego przedziału np. od 0 do 100 i zlicza ilość trafień danej liczby;
public class Worker extends SwingWorker<Long[], Void> {
private boolean finish = false;
private boolean pause = false;
private final Long[] result = new Long[100];
public Worker() {
super();
for (int i = 0; i < 100; i++) {
result[i] = 0L;
}
}
@Override
protected Long[] doInBackground() throws Exception {
Random random = new Random();
while (!finish) {
if (pause == true) {
synchronized(this) {
this.wait();
pause = false;
}
}
int i = random.nextInt(100);
synchronized(result) {
result[i]++;
}
publish();
// spowalniacz
Thread.sleep(100);
}
return result;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
public void setPause(boolean pause) {
this.pause = pause;
}
public boolean isPause() {
return pause;
}
@Override
protected void process(List<Void> chunks) {
super.process(chunks);
// synchronizacja na tablicy (tu i w doInBackground) nie jest potrzebna,
// jeśli nie przeszkadza nam, że wyniki cząstkowe mogą być rozjechane
synchronized(result) {
firePropertyChange("results", null, Arrays.copyOf(result, result.length));
}
}}
- klasa znajdująca się w innej paczce tworzy co pewien czas histogram tych wylosowanych liczb;
Dowolna klasa która ma np metodę setData(Long[] data) w której na podstawie dostarczonych danych rysuje histogram.
- trzecia klasa służy do komunikacji między tymi klasami i ewentualnemu sterowaniu przebiegiem klasy generującej liczby losowe (zatrzymuje, wznawia działanie).
To może być jakieś okienko np z 3 przyciskami. Klasa implementuje PropertyChangeListener i ma referencję do klasy rysującej histogram (może to być ta sama klasa).
Procedury podpięte pod przyciski:
private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
worker = new Worker();
worker.addPropertyChangeListener(this);
worker.execute();
}
private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {
if (worker.isPause() == true) {
synchronized(worker) {
worker.notifyAll();
}
} else {
worker.setPause(true);
}
}
private void finishButtonActionPerformed(java.awt.event.ActionEvent evt) {
worker.setFinish(true);
}
obsługa property change
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName()) && evt.getNewValue().equals(StateValue.DONE)) {
try {
Long[] result = worker.get();
rysowacz.setData(result);
} catch (ExecutionException ex) {
// obsługa błędów
} catch (InterruptedException ex) {
// obsługa błędów
}
} else if ("results".equals(evt.getPropertyName())) {
rysowacz.setData((Long[]) evt.getNewValue());
}
}
Klasa pierwsza i druga są oddzielnie od siebie.
Pozdrawiam