Jdialog does not design components in Java

Asked

Viewed 635 times

2

I am developing an application that will run 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 the JOptionPane, however as 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 making the instance of it and giving a .setVisible(true); it does not draw the components it has. The process behind it occurs normally, and the window closes, so it is not locking.

Follow code from 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);
    }

}

2 answers

3


Whether the window is modal or not, if you have a lengthy process to do you have to put it out of of Event Dispatcher thread. It was the click of a button or something like that that started the processing, right? If it is, it’s running on this thread, and until it finishes the Swing won’t draw anything.

Create a new thread for your processing. When it is finished, use the SwingUtilities.invokeLater to update the window again (this is necessary as 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);
}

2

The solution provided by @mgibsonbr is valid, but I believe that using SwingWorker is more appropriate, because this class was made precisely to work with parallelism with the EDT, performing heavy tasks on a thread a piece and then even allowing it to control and display the progress of the activity on the screen, as well as making it possible to find out when it ended and if it ended correctly, 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();

At this link there are more references about how this class works and how to use it.

Browser other questions tagged

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