How to close a Jdialog after you finish running a Thread?

Asked

Viewed 2,098 times

6

I have a configuration window that opens on the first run of the application I’m developing. After typing the directories that the application will run the user click save, some tests are run and finally runs a Thread.

I would like to make sure that after the execution of this Thread the configuration window closes by itself, but I tried to run dispose() and setVisible() and it disappears before running Thread.

// Evento para salvar os diretórios
btnSalvar.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {

        // Testa o campo com o diretório a ser indexado
        // Se está vazio
        if ((txtDirIndexado.getText().length() == 0 || Character
                .toString(txtDirIndexado.getText().charAt(0)).equals(
                        " "))) {
            JOptionPane
                    .showMessageDialog(panel,
                            "O campo com o diretório a ser indexado não pode estar em branco.");
        } else if ((txtDirIndice.getText().length() == 0 || Character
                .toString(txtDirIndexado.getText().charAt(0)).equals(
                        " "))) {
            JOptionPane
                    .showMessageDialog(panel,
                            "O campo com o diretório que guardará o índice não pode estar em branco.");

        } else {
            try {
                ArquivoDeConfiguracao.defineFonte(txtDirIndexado.getText());
                ArquivoDeConfiguracao.defineIndice(txtDirIndice.getText());
                ArquivoDeConfiguracao.definePrimeiraExecucao(1);
                // Janela de aguardo
                final JDialog janelaProgresso = new IndexAndo();

                // Cria um novo processo e mostra a janela
                new Thread(new Runnable() {
                    public void run() {
                        Indexador ind = new Indexador();
                        ind.iniciaIndexacao();

                        // Ao terminar fecha
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                janelaProgresso.setVisible(false);
                            }
                        });
                    }
                }).start();
                // Salva a data
                dispose();
                ArquivoDeConfiguracao.defineIndiceUltAtualizacao();
            } catch (IOException e) {
                // Gera erro
                e.printStackTrace();
            }
        }
    }

});

The code in full can be accessed in git.

Editing:

// Evento para salvar os direstórios
btnSalvar.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        // Testa o campo com o diretório a ser indexado
        // Se está vazio
        if ((txtDirIndexado.getText().length() == 0 || Character
                .toString(txtDirIndexado.getText().charAt(0)).equals(
                        " "))) {
            JOptionPane
                    .showMessageDialog(panel,
                            "O campo com o diretório a ser indexado não pode estar em branco.");
            // Se está vazio
        } else if ((txtDirIndice.getText().length() == 0 || Character
                .toString(txtDirIndexado.getText().charAt(0)).equals(
                        " "))) {
            JOptionPane
                    .showMessageDialog(panel,
                            "O campo com o diretório que guardará o índice não pode estar em branco.");
            // Se o diretório existe
        } else {
            try {
                ArquivoDeConfiguracao.defineFonte(txtDirIndexado.getText());
                ArquivoDeConfiguracao.defineIndice(txtDirIndice.getText());
                ArquivoDeConfiguracao.definePrimeiraExecucao(1);

                final JDialog janelaProgresso = new IndexAndo();

                new Thread(new Runnable() {
                    public void run() {
                        ProcessoIndexacao base = new ProcessoIndexacao();
                        base.start();
                        synchronized (base){
                            try {
                                base.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                janelaProgresso.setVisible(false);
                            }
                        });
                    }
                }).start();
                janelaProgresso.setVisible(true);
                // Salva a data
                ArquivoDeConfiguracao.defineIndiceUltAtualizacao();
            } catch (IOException e) {
                // Gera erro
                e.printStackTrace();
            }
        }
        dispose();
    }

public class ProcessoIndexacao extends Thread{
    public void run(){
        synchronized (this){
            Indexador ind = new Indexador();
            ind.iniciaIndexacao();
            notify();
        }
    }
}

2 answers

4


I haven’t seen your entire code, but if I understand your problem correctly you want a Thread to wait for another to be executed.

Basically what you need is to understand the concepts of wait() and notify().

Here’s an example I implemented while studying for Java certification proof:

public class WaitNotify {
    public static void main(String[] args) {
        //aqui você inicia uma nova Thread e manda ela rodar
        ThreadB b = new ThreadB();
        b.start();
        //Thread atual deve ter o "lock" da thread b,isso é necessário para chamar o wait()
        synchronized(b) {
            System.out.print("Waiting for b to complete...");
            try {
                //aqui você diz que a Thread atual deve esperar a Thread b terminar
                b.wait();
            } catch(InterruptedException e) { 
                e.printStackTrace();
            }
            System.out.println("Total is: " + b.total);
        }
    }
}

class ThreadB extends Thread {
    int total;
    //aqui sua Thread começa a rodar
    @Override
    public void run() {
        synchronized(this) {
            for(int i=0; i<16; i++) {
                total += i;
                try {
                    //um temporizador para sua Thread não acabar na velocidade da luz!
                    Thread.sleep(300);
                } catch(InterruptedException e) { 
                    e.printStackTrace();
                }
                //faz uma frescura
                if(i%2 == 0) {
                    System.out.print(".");
                }
            }
            System.out.println();
            //Thread avisa que terminou sua execução para quem possui o lock de b
            notify();
        }
    }
}

Remember that when you run a class that has a method main() you’re running a thread called main, as in the example above, the thread main is a thread like any other, so just make her wait another thread until it calls the notify().

  • I couldn’t implement 100%, when I run the thread it "hangs" and never ends.

  • @Strokes did you run my code or implement the threads in yours? If it’s in yours you could show us how it looked?

  • I implemented the suggestion adapting with my need. I posted in the question the new code

  • @Strokes looking looks all right to me.. I’ll see better at lunch, guentae

  • @Strokes I did some tests here to try to give in to the code, and I could not, then I appeared some doubts: what do you mean by lock? Does your code enter an infinite loop? Your screen appears and does not respond? Would you use debug to know exactly where the error is?

  • So, from what I saw him there in Wait(). He opens my windowProgress but doesn’t finish drawing, and he stays on it, I can resize it and everything. But the code doesn’t continue.

  • @Strokes you have two Thread, the first one will usually stop at the same Wait, until the other calls the notify. Did you come to see if the second reaches run the run? If so, where does it lock? Something else, I saw that between the setVisible true and false window has only one method, does it not run too fast not, or then too slow and you think stuck? Last observation point, do you really need another thread? Is there no way you can call the window inside your first code? Or at least pull the open code and close the window to the first thread.

  • It goes to the windowProgress.setVisible(true); and simply stops. Nothing else happens! This thread of mine is related to another question I asked here in the OR. Because I have the following logic: open the configuration window, fill and check the contents, open a "processing" window, run the process and close the two windows.

  • @Strokes in his example the instantiation of the window is outside the creation of the new thread, would be able to modify this?

  • From what I understand Java is waiting for my windowProgresso be closed to continue the code!

  • I managed to solve the problem, I’m posting below the question.

Show 6 more comments

0

Guys, I managed to solve my problem with the command below:

myJDialog.getOwner().dispose();

According to the documentation, this method has existed since version 1.2 of java.

  • 1

    This command will close not only the dialog, but the window from which it was called. Looking at the accepted answer, I don’t think that would solve the question.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.