使用多个框架时,我遇到隐藏组件未正确处理的问题。
简而言之,我无法处理其父级是隐藏框架的模态对话框。
例如:
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);
}
}
}
运行此示例:
TestFrame
。JOptionPane
。TimerTask
隐藏TestFrame
和dispose()
JOptionPane
。TestFrame
将变为可见,JOptionPane
将被附加。我知道我可以通过在隐藏JOptionPane
隐藏TestFrame
之前解决此问题:
- TestFrame.this.setVisible(false);
if (dialog != null) {
dialog.setVisible(false);
dialog.dispose();
dialog = null;
}
+ TestFrame.this.setVisible(false);
有人知道为什么会这样吗?我希望模态对话框即使在被处理时被隐藏也会消失。
答案 0 :(得分:4)
虽然您应该真正考虑对The Use of Multiple JFrames, Good/Bad Practice?的垃圾邮件评论,但以下是您看到此行为的原因的解释。
这是因为您在对话框之前隐藏了拥有窗口。执行此操作时,拥有的对话框将标记为showWithParent
,并且由于该标志,框架上的下一次setVisible(true)
调用将自动触发所拥有的对话框的显示。正如您在问题中所述,避免这种情况的唯一方法是首先隐藏拥有的对话框,然后隐藏拥有的窗口。
以下是Window.hide()
方法的摘录:
synchronized(ownedWindowList) {
for (int i = 0; i < ownedWindowList.size(); i++) {
Window child = ownedWindowList.elementAt(i).get();
if ((child != null) && child.visible) {
child.hide();
child.showWithParent = true; // See here the flag set to true
}
}
}
这里是Window.show()
方法的相应摘录:
for (int i = 0; i < ownedWindowList.size(); i++) {
Window child = ownedWindowList.elementAt(i).get();
if ((child != null) && child.showWithParent) { // Here theh flag is checked
child.show();
child.showWithParent = false; // flag is then reset
} // endif
}
顺便说一句,您可以使用javax.swing.Timer
(setRepeats(false)
),而不是使用此复杂的计时器/ TimerTask / invokeLater结构。 Swing计时器始终在Event Dispatching Thread上运行。