JDialog, setVisible(boolean) interrompe execução do método

8 respostas
wilsontads

Segue abaixo, código comentado com o que acontece.
Alguém já lidou com isso antes aqui ?

Thread th = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            newDialog = new NewDialog(this, true);
                            newDialog.setVisible(true);// Aqui, o JDialog é exibido, e  as linhas abaixo não são executadas.
                            newDialog.setLog("1...", true);//Método que no JDialog carrega em um JList os valores da String
							newDialog.setLog("2...", true);
							newDialog.setLog("3...", true);
							newDialog.setLog("4...", true);
							

                        } catch (Exception e) {
                            e.printStrackTrace();
                        }

                    }
                });

8 Respostas

R

Se o diálogo for modal, o método setVisible() será bloqueante, como está ocorrendo no seu caso.

wilsontads

Verdade, mais nesse caso preciso dele modal, existe uma maneira de contornar isto ?

TerraSkilll
Não sei qual a situação em que seu dialog é chamado, mas simplesmente alterar a ordem dos métodos não resolve?
Thread th = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            newDialog = new NewDialog(this, true);

                            // chama-se o setLog() antes de exibir o dialog
                            newDialog.setLog("1...", true);
                            newDialog.setLog("2...", true);
                            newDialog.setLog("3...", true);
                            newDialog.setLog("4...", true);

                            newDialog.setVisible(true);
                        } catch (Exception e) {
                            e.printStrackTrace();
                        }

                    }
                });

Abraço.

E

Iniciar uma thread e então dessa thread iniciar um JDialog ou outra coisa do Swing não é uma boa coisa, porque irá iniciar um componente do Swing em uma thread errada (não na thread do Swing). Isso costuma dar problemas esquisitos que não são triviais de consertar.

Em .NET isso gera até uma exceção. O Swing, nesse ponto, não é tão criterioso e deixa você fazer esses erros.

Se você precisa usar alguma coisa do Swing fora da thread do Swing, você deve usar SwingUtilities.invokeAndWait ou SwingUtilities.invokeLater e dentro do Runnable que esse invokeAndWait ou invokeLater exige, chame as APIs do Swing (como a visualização do JDialog).

wilsontads
dessa forma, ele da uma congelada no swing. =\
SwingUtilities.invokeAndWait(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            newDialog = new NewDialog(null, false);
                            newDialog.setVisible(true);
 newDialog.setLog("1...", true);  
            newDialog.setLog("2...", true);  
            newDialog.setLog("3...", true);  
            newDialog.setLog("4...", true);  

                        } catch (Exception e) {
                            MessageDialog.errorMessage("O teste falhou.\n" + e.getMessage(), "Erro");
                        }

                    }
                });
wilsontads

entanglement:
Iniciar uma thread e então dessa thread iniciar um JDialog ou outra coisa do Swing não é uma boa coisa, porque irá iniciar um componente do Swing em uma thread errada (não na thread do Swing). Isso costuma dar problemas esquisitos que não são triviais de consertar.

Em .NET isso gera até uma exceção. O Swing, nesse ponto, não é tão criterioso e deixa você fazer esses erros.

Se você precisa usar alguma coisa do Swing fora da thread do Swing, você deve usar SwingUtilities.invokeAndWait ou SwingUtilities.invokeLater e dentro do Runnable que esse invokeAndWait ou invokeLater exige, chame as APIs do Swing (como a visualização do JDialog).

Fiz como você disse, só que não resolve pra mim, dessa maneira minha tela sofre o congelamento, como se eu nem estivesse executando uma thread.

Ataxexe

wilsontads:
entanglement:
Iniciar uma thread e então dessa thread iniciar um JDialog ou outra coisa do Swing não é uma boa coisa, porque irá iniciar um componente do Swing em uma thread errada (não na thread do Swing). Isso costuma dar problemas esquisitos que não são triviais de consertar.

Em .NET isso gera até uma exceção. O Swing, nesse ponto, não é tão criterioso e deixa você fazer esses erros.

Se você precisa usar alguma coisa do Swing fora da thread do Swing, você deve usar SwingUtilities.invokeAndWait ou SwingUtilities.invokeLater e dentro do Runnable que esse invokeAndWait ou invokeLater exige, chame as APIs do Swing (como a visualização do JDialog).

Fiz como você disse, só que não resolve pra mim, dessa maneira minha tela sofre o congelamento, como se eu nem estivesse executando uma thread.

Na verdade isso não é uma solução para o seu problema. É algo obrigatório pra quem trabalha com Swing e que poderia ser uma solução, mas não deixe de usar as Threads do Swing.

E

Não faça invoke and wait, faça invokeLater, que dai é assincrono.

Criado 12 de setembro de 2012
Ultima resposta 13 de set. de 2012
Respostas 8
Participantes 6