I am having a problem with hidden components not being disposed properly when working with multiple frames.
In short, I cannot dispose a modal dialog whose parent is a hidden frame.
For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class MultipleFrameTest {
public static void main(String[] args) {
TestFrame test = new TestFrame();
FrameTester tester = new FrameTester(test);
tester.setVisible(true);
}
private static class TestFrame extends JFrame {
JDialog dialog;
java.util.Timer timer;
public TestFrame() {
super("Test Frame");
this.dialog = null;
this.timer = new java.util.Timer("Frame Timer");
fillFrame();
pack();
}
private void fillFrame() {
JButton dialogButton = new JButton("Launch Model Dialog");
dialogButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JOptionPane pane = new JOptionPane("Wait for 2 seconds",
JOptionPane.QUESTION_MESSAGE,
JOptionPane.OK_CANCEL_OPTION);
dialog = pane.createDialog(TestFrame.this, "Question");
timer.schedule(new TimerTask() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestFrame.this.setVisible(false);
if (dialog != null) {
dialog.setVisible(false);
dialog.dispose();
dialog = null;
}
}
});
}
}, 2 * 1000);
dialog.setVisible(true);
}
});
JPanel panel = new JPanel();
panel.add(dialogButton);
add(panel);
}
}
private static class FrameTester extends JFrame {
JFrame frame;
public FrameTester(JFrame frame) {
super("Frame Tester");
this.frame = frame;
fillFrame();
pack();
}
private void fillFrame() {
JButton toggleButton = new JButton("Toggle Frame Visibility");
toggleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
frame.setVisible(!frame.isVisible());
}
});
JPanel panel = new JPanel();
panel.add(toggleButton);
add(panel);
}
}
}
To run this example:
- Click the "Toggle Frame Visibility" button. This will show the
TestFrame
. - Click the "Launch Modal Dialog" button. This will pop up a
JOptionPane
. - Wait 2 seconds for a
TimerTask
to hide theTestFrame
anddispose()
theJOptionPane
. - Click the "Toggle Frame Visibility Button". The
TestFrame
will become visible and theJOptionPane
will see be attached.
I know that I can fix this by disposing the JOptionPane
before hiding the TestFrame
:
- TestFrame.this.setVisible(false);
if (dialog != null) {
dialog.setVisible(false);
dialog.dispose();
dialog = null;
}
+ TestFrame.this.setVisible(false);
Does anybody know why this is happening? I would expect the modal dialog to be gone even if it is hidden while it is being disposed.