Pessoal, no meu projeto eu criei uma tela que é responsável por definir (o usuário escolhe) o tipo de relatório a ser gerado e, ao clicar no botão “Gerar”, de acordo com a escolha do usuário (JComboBox), há um switch que define o caso. Até aí tudo bem, funciona perfeitamente. No entanto, eu percebi que há certo “atraso” entre acionar o botão Gerar e o carregamento do PDF com o relatório. Então para situar o usuário (se o relatório está sendo gerado ou não), eu resolvi colocar uma barra de progresso na tela, de forma que as coisas estão da seguinte forma:
public class TelaRelatorioCadastral extends javax.swing.JFrame {
private final int OPCAO_INVALIDA = 0;
private final Map parametros = new HashMap();
private volatile boolean terminado = true;
private Thread thredRelatorio;
private Thread threadBarraProgresso;
/**
* Creates new form TelaRelatorioCadastral
*/
public TelaRelatorioCadastral() {
UIManager.put("nimbusOrange", new Color(0, 102, 0));
initComponents();
setIcone();
configurarComponente();
}
/**[...]*/
private void btnGerarActionPerformed(java.awt.event.ActionEvent evt) {
if(cbxItemRelatorio.getSelectedIndex() != OPCAO_INVALIDA){
int opcao = cbxItemRelatorio.getSelectedIndex();
InputStream stream;
ResultSet resultSet;
Connection conexao;
ControlaThread controle;
parametros.put("logo", "/img/");
parametros.put("SUBREPORT_DIR", "/relatorio/");
terminado = false;
try{
switch(opcao){
case 1:
stream = getClass().getResourceAsStream(
"/relatorio/rc_plano_conta.jasper");
resultSet = dao.ContaContabil.retornarPlanoContas();
conexao = null;
construirRelatorio(stream, resultSet, conexao, this);
break;
case 5:
stream = getClass().getResourceAsStream(
"/relatorio/rc_cliente.jasper");
resultSet = null;
conexao = ConectaBancoDeDados.getConexao();
construirRelatorio(stream, resultSet, conexao, this);
break;
case 9:
stream = getClass().getResourceAsStream(
"/relatorio/rc_raca.jasper");
resultSet = dao.Raca.retornarRelatorioRaca();
conexao = null;
construirRelatorio(stream, resultSet, conexao, this);
break;
}
}catch(SQLException sqle){
System.out.println("ERRO: " + sqle.getMessage());
JOptionPane.showMessageDialog(this, "Relatório não foi gerado. "
+ sqle.getMessage());
}
}else{
JOptionPane.showMessageDialog(this, "Opção inválida!");
}
}
private void construirRelatorio(InputStream caminho, ResultSet resultados,
Connection conexao, TelaRelatorioCadastral telaCad)
throws SQLException{
final int CEM_MILISSEGUNDOS = 100;
final int DEZ_MILISSEGUNDOS = 10;
thredRelatorio = new Thread(new Runnable(){
@Override
public void run(){
if(resultados != null)
GeradorDeRelatorio.gerarRelatorio(caminho, parametros,
resultados, telaCad);
if(conexao != null)
GeradorDeRelatorio.gerarRelatorio(caminho, parametros,
conexao);
thredRelatorio = null;
}
});
threadBarraProgresso = new Thread(new Runnable(){
@Override
public void run(){
while(barraProgresso.getValue() < 100){
try{
Thread.sleep(CEM_MILISSEGUNDOS);
barraProgresso.setValue(barraProgresso.getValue()
+ DEZ_MILISSEGUNDOS);
descreverProgresso(barraProgresso.getValue());
if(barraProgresso.getValue() == 100)
threadBarraProgresso.interrupt();
}catch(InterruptedException iex){
System.out.println("ERRO: " + iex.getMessage());
break;
}
}
}
});
threadBarraProgresso.start();
thredRelatorio.start();
}
private void descreverProgresso(int progresso){
if(progresso < 25)
lblStatus.setText("Reunindo dados...");
if(progresso > 25 && progresso < 50)
lblStatus.setText("Obtendo parâmetros...");
if(progresso > 50 && progresso < 100)
lblStatus.setText("Construindo o relatório...");
if(progresso == 100)
lblStatus.setText("Concluído!");
}
/*[...]*/
}
O fato é que eu não consigo parar a Thread (deixar em state TERMINATED), pois elas ficam sempre no estado RUNNABLE (ao aplicar o método getState() na thread, aparece esse estado). Tanto é que se eu fechar a tela de emissão de relatórios e abrir novamente (a tela é aberta por meio de outra que contém menus de opções MenuBar), o combobox vem preenchido com a última opção escolhida e a barra de progresso em 100%. Eu confesso que é a primeira vez que estou trabalhando com threads e talvez não esteja codificando corretamente. Contudo, já tente utilizar flags para ‘encerrar’ as threds, mas aparentemente não resolve. O que será que estou fazendo de errado? Como trabalhar corretamente com Threads, Há outra forma de fazer a mesma coisa sem manipular threads diretamente?
Desde de já agradeço.