Закрытие модального 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) {}, что, вероятно, очень поможет.

Ответы на вопрос(5)

Ваш ответ на вопрос