Tela de espera com Swingworks

13 respostas
swingjava
M

Bem galera, minha duvida é a seguinte, tenho uma aplicação onde alguns processos são um pouco demorados e eu gostaria de apresentar uma tela de aguarde enquanto executo esses métodos “não um progressBar”, estou utilizando o SwingWorks pra fazer isso, porem quando eu chamo a minha tela de aguarde o SwingWorks não da continuidade pois ele vai pro código de exibição da tela, estou utilizando JDialog nas minhas telas, alguém pode me ajudar ?

13 Respostas

J

Você tem de fazer processos paralelos!

Pesquise sobre o uso de Threads.

Exemplo de execução paralela de um código juntamente com uma tela de splash:

Thread t1 = new Thread(() -> {
            envioEmailAutomatico(); //Execução de um código como por exemplo o envio de um e-mail
        });
        t1.start();//Inicia a primeira Thread

        Thread t2 = new Thread(() -> {
            Splash splash = new Splash();//Instância da jDialog com um gif escrito "Aguarde"

            splash.setUndecorated(true);//Remove as bordas da jDialog

            splash.setVisible(true);//Exibe a JDialog
            try {
                t1.join();//Executa em paralelo as duas Threads (Enquanto estiver enviando o e-mail a tela de splash fica visível)
            } catch (InterruptedException ex) {
                System.out.println("Erro -> ".concat(ex.getMessage()));
            }

            splash.dispose();//Fecho a tela de splash
        });
        t2.start();//Inicia a segunda Thread
M

Entendi, mais dessa forma estaria correto? Pois li em varios topicos que não é correto usar thread para trabalhar com Swing, o mais apropriado seria o SwingWorks

J

Cara na minha humilde opinião isso é muito relativo!
Tudo depende do contexto geral de aplicabilidade, cenário real de uso, problema x solução…
Não diria que esta forma é incorreta, eu diria que é uma das possíveis soluções a se utilizar, porém vale ressaltar que você deve analisar o problema como um todo, e decidir qual a melhor solução a ser utilizada.

M

Tentei adaptar este teu codigo, não funcionou aqu, deu o mesmo problema que já tenho, na hora em que ele da o setVisible(true); no meu JDialog de espera ele não consegue continuar o codigo até o t1.join();

J

posta seu código e o erro que está ocorrendo, fica mais fácil de visualizar e entender pra poder tentar te ajudar.

M

Esse é o JDialog de aguarde:

public class Aguarde2 extends JDialog {

private static final long serialVersionUID = 1L;

public Aguarde2() {
	setBounds(100, 100, 342, 101);
	setUndecorated(true);
	setModal(true);
	getContentPane().setLayout(null);
	
	JLabel lblAguarde = new JLabel("AGUARDE...");
	lblAguarde.setFont(new Font("Tahoma", Font.PLAIN, 16));
	lblAguarde.setHorizontalAlignment(SwingConstants.CENTER);
	lblAguarde.setBounds(10, 11, 322, 79);
	getContentPane().add(lblAguarde);
}

}

e Esse o JDialog onde faço a chamada:

Thread t1 = new Thread(() -> {
        importXML();
    });
    t1.start();

    Thread t2 = new Thread(() -> {
        Aguarde2 aguarde = new Aguarde2();

        aguarde.setVisible(true);//Exibe a JDialog
        try {
            t1.join();
        } catch (InterruptedException ex) {
            System.out.println("Erro -> ".concat(ex.getMessage()));
        }
        aguarde.dispose();
    });
    t2.start();
J

E qual é o log erro ?

M

Ai que ta, não da erro algum, eu fiz um teste de colocar um sysout antes e depois do t1.join pra verificar como estava passando, porém nenhum dos dois aparecem, pelo que vi, quando faço aguarde.setVisible(true); a compilação para na tela de aguarde e só continua quando consigo fechar ela

J

Alterei a sua classe Aguarde2 e fiz um teste simples aqui e funcionou perfeitamente!

public class Aguarde2 extends JDialog {

    private static final long serialVersionUID = 1L;

    public Aguarde2() {
        setBounds(100, 100, 342, 101);
        setUndecorated(true);        
        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        JLabel lblAguarde = new JLabel("AGUARDE...");
        lblAguarde.setFont(new Font("Tahoma", Font.PLAIN, 16));
        lblAguarde.setHorizontalAlignment(SwingConstants.CENTER);
        lblAguarde.setBounds(10, 11, 322, 79);
        getContentPane().add(lblAguarde);
    }

}
M

Funciona, só que tem um pequeno problema, como uso JDialog como modal, quando chamo o Aguarde2 ele fica por trás do JDialog, e se eu setar o modal no Aguarde2 ele trava novamente na tela, acredito que não tem uma solução para esse problema devido o uso do modal, ou você saberia como posso contornar isso ?

J

Cara esse problema dos modais é complicado, eu tenho uma classe para tratar esse tipo de coisa, mas só funciona entre frame x frame e frame x dialog.
Dialog pra Dialog não sei se tem uma forma de tratar.

M

Valeu cara, agradeço pela ajuda, vou ver oque consigo fazer por aqui pra contornar esses problemas

J

Talvez quem conheça alguma forma de contornar esse problema entre transição de modal entre JDialogs é o @staroski.

Criado 23 de novembro de 2018
Ultima resposta 29 de nov. de 2018
Respostas 13
Participantes 2