Swing: How do I run a job from AWT thread, but after a window was layed out?

Posted by java.is.for.desktop on Stack Overflow See other posts from Stack Overflow or by java.is.for.desktop
Published on 2010-12-27T09:10:33Z Indexed on 2010/12/27 9:54 UTC
Read the original article Hit count: 190

Filed under:
|
|
|
|

My complete GUI runs inside the AWT thread, because I start the main window using SwingUtilities.invokeAndWait(...).

Now I have a JDialog which has just to display a JLabel, which indicates that a certain job is in progress, and close that dialog after the job was finished.

The problem is: the label is not displayed. That job seems to be started before JDialog was fully layed-out.

When I just let the dialog open without waiting for a job and closing, the label is displayed.

The last thing the dialog does in its ctor is setVisible(true).
Things such as revalidate(), repaint(), ... don't help either.

Even when I start a thread for the monitored job, and wait for it using someThread.join() it doesn't help, because the current thread (which is the AWT thread) is blocked by join, I guess.

Replacing JDialog with JFrame doesn't help either.

So, is the concept wrong in general? Or can I manage it to do certain job after it is ensured that a JDialog (or JFrame) is fully layed-out?

Simplified algorithm of what I'm trying to achieve:

  • Create a subclass of JDialog
  • Ensure that it and its contents are fully layed-out
  • Start a process and wait for it to finish (threaded or not, doesn't matter)
  • Close the dialog

I managed to write a reproducible test case:

EDIT Problem from an answer is now addressed: This use case does display the label, but it fails to close after the "simulated process", because of dialog's modality.

import java.awt.*;
import javax.swing.*;

public class _DialogTest2 {

  public static void main(String[] args)
      throws Exception {
    SwingUtilities.invokeAndWait(new Runnable() {
      final JLabel jLabel = new JLabel("Please wait...");

      @Override
      public void run() {
        JFrame myFrame = new JFrame("Main frame");
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setSize(750, 500);
        myFrame.setLocationRelativeTo(null);
        myFrame.setVisible(true);

        JDialog d = new JDialog(myFrame, "I'm waiting");
        d.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);

        d.add(jLabel);
        d.setSize(300, 200);
        d.setLocationRelativeTo(null);
        d.setVisible(true);

        SwingUtilities.invokeLater(new Runnable() {

          @Override
          public void run() {
            try {
              Thread.sleep(3000); // simulate process
              jLabel.setText("Done");
            } catch (InterruptedException ex) {
            }
          }

        });

        d.setVisible(false);
        d.dispose();

        myFrame.setVisible(false);
        myFrame.dispose();
      }
    });
  }
}

© Stack Overflow or respective owner

Related posts about java

Related posts about multithreading