Thread + IReport (Trava a aplicação) [RESOLVIDO]

7 respostas
R

Olá, bom tentei implentar uma Thread para gerar relatórios porem não está funcionando continua travando a aplicação, estou fazendo algo errado?

Obrigado.

public class ThreadRelatorioClientes implements Runnable {

	public ThreadRelatorioClientes(){}

        @Override
	public void run() {
		iniciaCarregar();
		try{
                   EventQueue.invokeLater(new Runnable() {
                   @Override
                   public void run() {
                        try {
                            new Gerar().geraRelatorio("Clientes.jasper", "Relatório de Clientes", 0);
                        } catch (JRException ex) {
                            Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (SQLException ex) {
                            Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
                        }
                       }
                   });
                }catch(Exception e){

		}finally{
                    paraCarregar();
		}
		return;
	}
 }

7 Respostas

R

Complementando o código

public static void iniciaCarregar() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run(){
                barraStatusLabel.setText(msgCarregando);
                barraDeProgresso.setIndeterminate(true);
            }
        });
   }
   public static void paraCarregar() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run(){
                barraStatusLabel.setText(msgPronto);
                barraDeProgresso.setIndeterminate(false);
            }
        });
   }

é necessário colocar o Sleep?

V

O invokeLater não cria nenhuma thread. Ela pega o código de um Runnable e roda na Thread do Swing. Caso você esteja num código de botão (que já está na thread do Swing), uma chamada a invokeLater simplesmente executará o Runnable.

Para criar novas threads, use a classe Thread e o método start().

Dentro da nova thread, aí sim, você usa o invokeLater para alterar o status do que for componente Swing. Mas com certeza essa linha não pode estar num invokeLater:

new Gerar().geraRelatorio("Clientes.jasper", "Relatório de Clientes", 0);
R

[quote=ViniGodoy]O invokeLater não cria nenhuma thread. Ela pega o código de um Runnable e roda na Thread do Swing. Caso você esteja num código de botão (que já está na thread do Swing), uma chamada a invokeLater simplesmente executará o Runnable.

Para criar novas threads, use a classe Thread e o método start().

Dentro da nova thread, aí sim, você usa o invokeLater para alterar o status do que for componente Swing. Mas com certeza essa linha não pode estar num invokeLater:

new Gerar().geraRelatorio("Clientes.jasper", "Relatório de Clientes", 0);

bom tem esse codigo no botao

Thread barra = new Thread(new ThreadRelatorioClientes(), "Gerando Relatorio");
        barra.setDaemon(true);
        barra.setPriority(3);
        barra.start();

Onde estou errando?

V

Você está errando ao chamar aquela linha que indiquei no invokeLater. Isso vai fazer com que essa Thread devolva o processamento para a Thread do Swing e aí, a tela trava.

R

Consegui, era isso mesmo! estava batendo cabeça aqui há algum tempo! obrigado!

J

Desculpe mexer nesse assunto ainda, mas gostaria da opinião do ViniGodoy sobre esse meu código que faz algo semelhante. Não tenho certeza sobre a abordagem de gerar o relatório dentro do JDialog está correta.

Tenho esse método que retorna um JDialog com o JViewer dentro dele:
public JDialog showReport(JInternalFrame frame, String nomeArquivoJRXML, Map parametros, String titulo) throws JRException, NullPointerException {
        String jasper = "reports/" + nomeArquivoJRXML + ".jasper";
        InputStream ips = transfex.reports.Report.class.getResourceAsStream(jasper);
        JasperPrint print = JasperFillManager.fillReport(ips, parametros, Conectar.getCon());
        JRViewer viewer = new JRViewer(print);

        JDialog window = new JDialog(JOptionPane.getFrameForComponent(frame), titulo, true);
        java.awt.Dimension tamanho = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        int largura = tamanho.width; 
        int altura = tamanho.height - 80;
        int top = ((tamanho.width - largura) / 2);
        int left = ((tamanho.height - altura) / 2) - 10;
        window.setAlwaysOnTop(true);
        window.setResizable(true);
        window.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        window.setBounds(top, left, largura, altura);
        window.getContentPane().add(viewer);
        return window;
    }
Aí no meu UI tenho esse código para gerar o relatório e depois mostrar a janela:
Thread t = new Thread()                                     {

    @Override
    public void run() {
        glassPane.setVisible(true, "Gerando relatório...");

        /* ... */

        JDialog winReport = null;
        try {
            winReport = new Report().showReport(frame, "RELATORIO_MANIFESTO", parametros, titulo);
        } catch (JRException ex) {
            Logger.getLogger(ManifestoUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NullPointerException ex) {
            Logger.getLogger(ManifestoUI.class.getName()).log(Level.SEVERE, null, ex);
        }
        final JDialog winReport2 = winReport;

        SwingUtilities.invokeLater(new Runnable()                                     {

            @Override
            public void run() {
                if(winReport2 != null){
                    winReport2.setVisible(true);
                }
                glassPane.setVisible(false);
            }
        });
    }
};
t.start();
V

Está certo sim.

Sobre o iReport especificamente não posso te dizer, já que não usei. Eu geralmente gerava relatórios em planilhas excel.

Criado 18 de janeiro de 2011
Ultima resposta 21 de jan. de 2011
Respostas 7
Participantes 3