JDialog does not draw the components in Java

2

I'm developing an application that will execute a processing soon, and I want a message warning that the process is running stay on the screen while it does this processing. I tried to do with JOptionPane , but since it is a modal window by default the processing will only continue if it is closed. So I made a simple window with JDialog , but after doing the instance of it and giving a .setVisible(true); it does not draw the components that it owns. The process behind it usually occurs, and the window closes, so it is not crashing.

Follow the code in the window:

package main;

import java.awt.BorderLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import java.awt.Font;

public class IndexAndo extends JDialog {

    private final JPanel contentPanel = new JPanel();
    private JLabel lblIstoPodeLevar;
    private JLabel lblIndexandoAguarde;

    /**
     * Create the dialog.
     */
    public IndexAndo() {
        setTitle("IR - Indexar");
        setBounds(100, 100, 450, 150);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        {
            lblIstoPodeLevar = new JLabel("Isto pode levar alguns minutos.");
            lblIstoPodeLevar.setFont(new Font("Tahoma", Font.BOLD, 11));
        }
        {
            lblIndexandoAguarde = new JLabel("Executando indexa\u00E7\u00E3o, aguarde.");
            lblIndexandoAguarde.setFont(new Font("Tahoma", Font.BOLD, 11));
        }
        GroupLayout gl_contentPanel = new GroupLayout(contentPanel);
        gl_contentPanel.setHorizontalGroup(
            gl_contentPanel.createParallelGroup(Alignment.TRAILING)
                .addGroup(gl_contentPanel.createSequentialGroup()
                    .addContainerGap(126, Short.MAX_VALUE)
                    .addGroup(gl_contentPanel.createParallelGroup(Alignment.LEADING)
                        .addGroup(Alignment.TRAILING, gl_contentPanel.createSequentialGroup()
                            .addComponent(lblIndexandoAguarde)
                            .addGap(115))
                        .addGroup(Alignment.TRAILING, gl_contentPanel.createSequentialGroup()
                            .addComponent(lblIstoPodeLevar)
                            .addGap(118))))
        );
        gl_contentPanel.setVerticalGroup(
            gl_contentPanel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_contentPanel.createSequentialGroup()
                    .addGap(26)
                    .addComponent(lblIndexandoAguarde)
                    .addGap(9)
                    .addComponent(lblIstoPodeLevar)
                    .addContainerGap(39, Short.MAX_VALUE))
        );
        contentPanel.setLayout(gl_contentPanel);
    }

}
    
asked by anonymous 21.03.2014 / 19:20

2 answers

3

Regardless of whether the window is modal or not, if you have a time-consuming process you have to put it off event dispatcher thread . It was the click of a button or something that started processing, right? If it is, it is running on that thread, and while it does not finish Swing will not draw anything.

Create a new thread for processing. When it finishes, use SwingUtilities.invokeLater to refresh the window again (this is necessary because the Swing library is not thread-safe):

void actionPerformed(ActionEvent e) {
    // Ou seja lá como você está iniciando seu processamento

    // Sua janela de progresso vem aqui. Não importa se é modal ou não.
    final JDialog janelaProgresso = new Indexando();

    new Thread(new Runnable() {
        public void run() {
            // Seu processamento vem aqui

            // Ao terminar...
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    janelaProgresso.setVisible(false);
                }
            });
        }
    }).start();

    janelaProgresso.setVisible(true);
}
    
21.03.2014 / 19:35
2

The solution given by @mgibsonbr is valid, but I believe using SwingWorker is more appropriate, since this class was done just to work with EDT by performing heavy tasks on a separate thread and then even allowing you to control and display the progress of the activity on the screen, as well as enabling you to find out when it's gone and gone properly without having to implement anything too complex.

An example of how it could be implemented:

SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>(){

    final JDialog janelaProgresso = new Indexando();

    @Override
    protected Void doInBackground() throws Exception {
        publish();
        // aqui dentro você invoca a classe/metodo com a tarefa demorada
        return null;
    }

    @Override
    protected void process(List<Void> chunks) {
        janelaProgresso.setVisible(true);
    }

    @Override
    protected void done() {
        janelaProgresso.setVisible(false);
    }

};
worker.execute();

In this link there are more references on how this class works and how to use it .

    
29.10.2017 / 22:17