Olá colegas,
estou quebrando a cabeça para resolver uma situação.
Tenho uma aplicação em SWT e permito executar um processamento em que eu não tenho controle do tempo, por isso resolvi colocar um ProgressBar e jogar o processo de negócio em uma Thread.
Até aí tudo bem, parece ser simples, e funciona mas somente uma vez, na segunda gera a seguinte exceção:
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at swt.progress.MainPanel.runProcess(MainPanel.java:56)
at swt.progress.MainPanel.access$0(MainPanel.java:52)
at swt.progress.MainPanel$1.handleEvent(MainPanel.java:31)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:928)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3348)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2968)
at swt.progress.MainPanel.run(MainPanel.java:64)
at swt.progress.StartMain.main(StartMain.java:7)
Criei uma situação semelhante do meu caso no código abaixo.
Alguém se aventura em solucionar esse mistério?
Classe main:
public class StartMain {
public static void main(String[] args) {
MainPanel mainPanel = new MainPanel();
mainPanel.run();
mainPanel.done();
}
}
Painel principal
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class MainPanel {
private Display display;
private Shell shell;
private Process process;
public MainPanel() {
this.display = new Display();
this.shell = new Shell(this.display);
this.process = new Process();
this.initGUI();
}
private void initGUI() {
shell.setLayout(new GridLayout(3, true));
Button button = new Button(shell, SWT.NONE);
button.setText("3s");
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
runProcess(3000);
}
});
button = new Button(shell, SWT.NONE);
button.setText("5s");
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
runProcess(5000);
}
});
button = new Button(shell, SWT.NONE);
button.setText("10s");
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
runProcess(10000);
}
});
}
private void runProcess(long time){
this.process.setTimeProcess(time);
Progress progress = new Progress(this.shell);
this.process.registerInterest(progress);
this.process.start();
progress.run();
}
public void run() {
shell.setSize(500, 300);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public void done() {
display.dispose();
}
}
Classe que tem o progressbar
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
public class Progress implements Observer {
private Shell shell;
public Progress(Shell shell) {
this.shell = new Shell(shell, SWT.TITLE | SWT.APPLICATION_MODAL);
this.initGUI();
}
private void initGUI() {
this.shell.setText("Aguarde...");
this.shell.setLayout(new GridLayout());
ProgressBar progressBar = new ProgressBar(this.shell, SWT.HORIZONTAL | SWT.INDETERMINATE);
GridData data = new GridData (SWT.CENTER, SWT.CENTER, false, false);
progressBar.setLayoutData (data);
}
public void closeProgress(){
this.shell.dispose();
}
public void run() {
Rectangle displayBounds = this.shell.getDisplay().getBounds();
int minWidth = (displayBounds.width / 2) - 300;
int minHeight = (displayBounds.height / 2) - 250;
int left = (displayBounds.width - minWidth) / 2;
int top = (displayBounds.height - minHeight) / 2;
this.shell.setBounds(left, top, minWidth, minHeight);
this.shell.open();
}
@Override
public void sendNotify() {
this.shell.getDisplay().syncExec(new Runnable(){
@Override
public void run() {
shell.dispose();
}
});
}
}
Classe Thread que executa o processo
import java.util.ArrayList;
import java.util.List;
public class Process extends Thread {
private long timeProcess;
private List<Observer> observers = new ArrayList<Observer>();
public void setTimeProcess(long time){
this.timeProcess = time;
}
public void run(){
try {
int contador = 0;
System.out.println("iniciando processo..." + (this.timeProcess/1000) + "s");
while(contador < (this.timeProcess/1000)){
contador++;
System.out.println("contador " + contador);
Thread.sleep(1000);
}
System.out.println("fim do processo.");
this.notifyObservers();
} catch (Exception e) {
System.err.println("ocorreu um erro aqui: " + this.getClass());
e.printStackTrace();
}
}
public void registerInterest(Observer obs) {
this.observers.add(obs);
}
private void notifyObservers(){
for (final Observer obs : this.observers) {
obs.sendNotify();
}
}
}
Ah, a interface Observer
public interface Observer {
public void sendNotify();
}