Закрытие модального JInternalFrame
Я следовал за подходом 2это руководство, так что теперь у меня есть ModalInternalFrame, который блокирует ввод всех остальных кадров, как я хотел. Тем не менее, я сделал одно изменение из примера, и теперь у меня есть две проблемы.
Перемена
Я удалил JOptionPane, потому что весь смысл в том, чтобы показать мою собственную панель. Чтобы закрыть его, я установилcloseable
вtrue
и добавил InternalFrameListener с тем же кодом, что и слушатель примера для JOptionPane. Это не работает, поэтому я также добавил код в конце doDefaultCloseAction.
Проблемы
Рамка ModalInternal никогда не исчезает. Я думаю, что какое-то исключение выбрасывается, но ...Я не вижу никаких исключений, и не знаю, куда они идут. Обычно в режиме отладки Eclipse останавливается непосредственно перед тем, как исключение передается UncaughtExceptionHandler, но в этом случае этого не происходит.Код
Если мое описание проблемы не помогает, вот моя версия 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(); }
}
Обновить: Я обнаружил, что модальные диалоговые окна вполне соответствуют моим потребностям, но если у кого-то есть идея, я буду рад ее услышать. Одна вещь, которую я не пробовал - это обернуть каждый метод в try {} catch (Exception e) {}, что, вероятно, очень поможет.