0

I am creating my own dialog which is basically a JPanel set as the glasspane on a JFrame. I want to make my dialog modal in the sense that all the code after the setVisible() is not executed while the dialog is visible and once the dialog is closed, the rest of the code after the setVisible() must continue.

To achieve this I am using a thread to display my dialog. I know that the SwingUtilities.invokeLater() method must be used to update the gui because it is executed in another thread. However my dialog does not show on the screen.

Here is my code example:

final JFrame frame = new JFrame();
frame.setBounds(0, 0, 1024, 768);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);

JButton button = new JButton("Text");
button.setBounds(200, 300, 110, 50);
button.addActionListener(new ActionListener() {

    boolean dispose;

    public void actionPerformed(ActionEvent e) {
        try {
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    final JPanel panelGlass = new JPanel(null);
                    panelGlass.setBounds(frame.getBounds());
                    panelGlass.setBackground(Color.red);
                    frame.setGlassPane(panelGlass);

                    JButton btnClose = new JButton("close");
                    btnClose.setBounds(100, 100, 110, 50);
                    btnClose.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                            dispose = true;
                        }
                    });
                    panelGlass.add(btnClose);

                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            dispose = false;
                            panelGlass.setVisible(true);
                        }
                    });

                    while (!dispose) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    panelGlass.setVisible(false);
                }
            });
            thread.start();
            thread.join();
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
});
frame.getContentPane().add(button);

frame.setVisible(true);

Why is my dialog not shown?

bouncer
  • 173
  • 10

3 Answers3

1

The problem is here:

thread.start();
thread.join();

You start the thread but you immediately wait for it to finish. This blocks the UI thread and doesn't allow it to process your SwingUtilities.invokeLater update.

I really don't see any good reason for that join call to exist.

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • As I explained in my question, i need the code execution to wait for my dialog to close before it continues, similar to JOptionPane.showMessageDialog(null, "This is a message"); – bouncer Nov 02 '12 at 06:38
  • @bouncer: Well this clearly won't work as it is. But as I recall from using swing, you don't actually need a new thread to display another control on top of the main one. You just need to figure out a way to not make the main control accessible until the new one is closed. – Tudor Nov 02 '12 at 07:01
1

You can't do that like that since

  • you're accessing Swing components from a thread other than the event disptach thread
  • the event disptach thread, where all the UI painting happens, is completely blocked by the call to Thread.join().

You should be able to do something like what you want with Java 7's SecondaryLoop, but I've never used it.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1
  • frame.getRootPane.setGlassPane

  • your idea is good, but have to consume() events came from keyboard, add there KeyListener only with e.consume() because GlassPane to consume only mouse events

  • create whole Gui with GlassPane too,

  • inside actionperformed to show prepared GlassPane, then to start a Runnable.Thread

  • I have one question here about multiply glasspane

  • use JLayer Java7, based on JXLayer Java6

  • your question is booking example for why reason is SwingWorker implemented in Java

reply from cellphone

mKorbel
  • 109,525
  • 20
  • 134
  • 319