我遵循了方法2本指南,所以现在我有一个 ModalInternalFrame 可以阻止所有其他框架的输入,正如我想要的那样。但是,我对示例进行了一项更改,现在遇到了两个问题。
改变
我删除了 JOptionPane,因为重点是显示我自己的窗格。为了使它接近,我设置closeable
to true
,并添加了一个InternalFrameListener,其代码与示例中的JOptionPane 侦听器相同。这不起作用,所以我还在 doDefaultCloseAction 的末尾添加了代码。
问题
- ModalInternal 框架永远不会消失。我认为正在抛出一些异常,但是......
- 我看不到任何抛出的异常,也不知道它们要去哪里。通常在调试模式下,Eclipse 将在将异常传递给 UncaughtExceptionHandler 之前停止,但在本例中不会发生这种情况。
The Code
如果我对问题的描述没有帮助,这是我的 ModalInternalFrame 版本。如果您想要更多代码,我也可以发布。抱歉,太长了,但我尽力使其尽可能简洁。
public class ModalInternalFrame extends JInternalFrame {
public ModalInternalFrame(String title, JRootPane rootPane,
Component desktop) {
super(title, false, true, false, false);
// create opaque glass pane
final JPanel glass = new JPanel();
glass.setOpaque(false);
// Attach mouse listeners
MouseInputAdapter adapter = new MouseInputAdapter() { };
glass.addMouseListener(adapter);
glass.addMouseMotionListener(adapter);
this.addInternalFrameListener(new InternalFrameListenerAdapter() {
public void internalFrameClosed(InternalFrameEvent e) { close(); }
public void internalFrameClosing(InternalFrameEvent e){ close(); }
});
// Change frame border
putClientProperty("JInternalFrame.frameType", "optionDialog");
// Size frame
Dimension size = getPreferredSize();
Dimension rootSize = desktop.getSize();
setBounds((rootSize.width - size.width) / 2,
(rootSize.height - size.height) / 2, size.width, size.height);
desktop.validate();
try { setSelected(true); }
catch (PropertyVetoException ignored) { }
glass.add(this); // Add modal internal frame to glass pane
rootPane.setGlassPane(glass); // Change glass pane to our panel
glass.setVisible(true); // Show glass pane, then modal dialog
}
private void close(){
if (isVisible()) {
try { setClosed(true); }
catch (PropertyVetoException ignored) { }
setVisible(false);
rootPane.getGlassPane().setVisible(false);
}
}
@Override public void doDefaultCloseAction() {
super.doDefaultCloseAction();
close();
}
@Override public void setVisible(boolean flag) {
super.setVisible(flag);
if (flag) startModal();
else stopModal();
}
private synchronized void startModal() {
try {
if (SwingUtilities.isEventDispatchThread()) {
EventQueue theQueue = getToolkit().getSystemEventQueue();
while (isVisible()) {
AWTEvent event = theQueue.getNextEvent();
Object source = event.getSource();
if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch();
} else if (source instanceof Component) {
((Component) source).dispatchEvent(event);
} else if (source instanceof MenuComponent) {
((MenuComponent) source).dispatchEvent(event);
} else {
System.err.println("Unable to dispatch: " + event);
}
}
} else { while (isVisible()) { wait(); } }
} catch (InterruptedException ignored) {
}
}
private synchronized void stopModal() { notifyAll(); }
}
Update:我发现模式对话框很适合我的需求,但如果有人有想法,我会很高兴听到它。我没有尝试过的一件事是将每个方法包装在 try {} catch (Exception e){} 中,这可能会有很大帮助。