-2
This is the first time I’ve been working with Threads. I created two threads, one to run the report generator (iReport) and one to operate a progress bar (Jprogressbar). However, even using flag, Thread is not terminated (state - TERMINATED), that is, it remains in the RUNNABLE state. See:
package util;
import java.io.InputStream;
import java.sql.ResultSet;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JProgressBar;
import visao.TelaRelatorioCadastral;
/**
*
* @author JFSJUNIOR
*/
public class ControlaThread{
private Thread threadBarraProgresso;
private Thread threadEmissaoRelatorio;
private final AtomicBoolean rodando = new AtomicBoolean(false);
private JProgressBar progresso;
private InputStream fluxo;
private ResultSet dados;
private TelaRelatorioCadastral tela;
private Map param;
public ControlaThread(JProgressBar barraProgresso,
InputStream caminho, ResultSet resultados,
TelaRelatorioCadastral telaCad, Map paramentros){
progresso = barraProgresso;
fluxo = caminho;
dados = resultados;
tela = telaCad;
param = paramentros;
}
public void start(){
threadBarraProgresso = new Thread(new Runnable(){
@Override
public void run() {
rodando.set(true);
while(progresso.getValue() < 100 && rodando.get()){
try {
Thread.sleep(100);
progresso.setValue(progresso.getValue() + 10);
} catch (InterruptedException iex) {
System.out.println("ERRO: " + iex.getMessage());
}
}
}
});
threadEmissaoRelatorio= new Thread(new Runnable(){
@Override
public void run() {
if(rodando.get())
GeradorDeRelatorio.gerarRelatorio(fluxo, param, dados, tela);
}
});
threadBarraProgresso.start();
threadEmissaoRelatorio.start();
}
public void stop(){
rodando.set(false);
System.out.println("Finalizado");
}
}
Everything works, but the screen that calls this class always comes set with the last option chosen (in a Jcombobox) and the previous bar is completed (100%). How to stop Threads without using the deprecated stop() because the flags are not working? Where am I missing?
Additional information
1 - Checking the name of threads in the stop method:
public void stop(){
rodando.set(false);
System.out.println("Finalizado");
System.out.println("NomeThreadBE: " + threadBarraProgresso.getName());
System.out.println("NomeThreadER: " + threadEmissaoRelatorio.getName());
}
generates:
run:
Finalizado
NomeThreadBE: Thread-2
NomeThreadER: Thread-3
Here the button method:
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;
controle = new ControlaThread(barraProgresso, stream, resultSet, this, parametros);
controle.start();
controle.stop();
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!");
}
}
Note: As I only built the race report, I am using case 9 for the tests.
===========================================================================
Updated code
Case 9 of the button:
case 9:
stream = getClass().getResourceAsStream(
"/relatorio/rc_raca.jasper");
resultSet = dao.Raca.retornarRelatorioRaca();
conexao = null;
construirRelatorio(stream, resultSet, conexao, this);
break;
and the previous class code I transferred to the build method with some modifications:
private void construirRelatorio(InputStream caminho, ResultSet resultados,
Connection conexao, TelaRelatorioCadastral telaCad)
throws SQLException{
final int SONECA = 500;
final int PERIODO = 10;
thredRelatorio = new Thread(new Runnable(){
@Override
public void run(){
rodando.set(true);
if(rodando.get()){
if(resultados != null){
GeradorDeRelatorio.gerarRelatorio(caminho, parametros,
resultados);
}
if(conexao != null)
GeradorDeRelatorio.gerarRelatorio(caminho, parametros,
conexao);
}
stop();
}
});
threadBarraProgresso = new Thread(new Runnable(){
@Override
public void run(){
rodando.set(true);
while(barraProgresso.getValue() < 100 && rodando.get()){
try{
Thread.sleep(SONECA);
barraProgresso.setValue(barraProgresso.getValue()
+ PERIODO);
descreverProgresso(barraProgresso.getValue());
}catch(InterruptedException iex){
System.out.println("ERRO: " + iex.getMessage());
break;
}
}
thredRelatorio.start();
telaCadastro.dispose();
reconfigurarCampos();
}
});
threadBarraProgresso.start();
}
The Stop method:
private void stop(){
rodando.set(false);
System.out.println("Finalizado");
System.out.println("NomeThreadBE: " + threadBarraProgresso.getName());
System.out.println("NomeThreadER: " + thredRelatorio.getName());
System.out.println("StatusBE: " + threadBarraProgresso.getState());
System.out.println("StatusER: " + thredRelatorio.getState());
}
And the method that describes progress:
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!");
}
I put the report thread start() method at the end (after while) of the progress bar thread to ensure that the report thread will only be called when the progress bar thread has TERMINATED status. I tried this using John, but it is difficult to hit the threads' 'time' (hence I would have to put the value of NAP very low), since in certain situations the report is generated with the progress bar at 20%, 30%, hence the bar thread enters WAITING or TIMED-WAITING. I ran the test generating the report without calling the method JasperViewer.viewReport(jasperPrint, false);
to see if this is what kept the thread in RUNNABLE, but to no avail.
Thanks in advance.
in the current context there you have at least 3 threads running, the main and two more, how do you know that the one that is runnable is the one that should have finished? another detail, your thread.Leep there is 100 milliseconds, if your bar is worth 100, in a second it already completes from the moment you give start
– Lucas Miranda
Yes, the main thread and the two I created. I do: threadBarraProgresso.getState(), threadEmissaoRelatorio.getState(), for example. Also I confirm threadBarraProgressio.getName(), threadEmissaoRelatorio.getName() or getID() to know.
– Silva Júnior
but where is this in your example? where is the stop call?
– Lucas Miranda
I put more details.
– Silva Júnior