дождитесь закрытия jdialog - PullRequest
       9

дождитесь закрытия jdialog

7 голосов
/ 22 октября 2011

У меня есть класс FilePathDialog, который расширяет JDialog, и этот класс вызывается из некоторого класса X. Вот метод в классе X

    projectDialog = new FilePathDialog();   
    projectDialog.setVisible(true);

    projectDialog.addWindowListener(new WindowAdapter() {            
        public void windowClosing(WindowEvent e) {
            System.out.println("Window closing");
            try {
                doWork();
            } catch (Throwable t) {
                t.printStackTrace();
            }                
        }

        public void windowClosed(WindowEvent e) {
            System.out.println("Window closed");
            try {
                doWork();
            } catch (Throwable t) {
                t.printStackTrace();
            }                
        }
    });     

doWork никогда не вызывается при закрытии окна JDialog. Все, что я пытаюсь сделать, это дождаться закрытия JDialog, прежде чем он продолжит работу с методом. Я также пытался использовать SwingWorker и Runnable, но это не помогло.

Ответы [ 3 ]

17 голосов
/ 22 октября 2011

Опять же, клавиша является модальным диалоговым окном или нет ?

Если это модально, то WindowListener не нужен, так как вы будете знать, что диалог был обработан, так как код возобновится сразу после вашего вызова к setVisible(true) в диалоге.то есть, это должно работать:

projectDialog = new FilePathDialog();   
projectDialog.setVisible(true);
doWork(); // will not be called until the dialog is no longer visible

Если, с другой стороны, он не работает в режиме, тогда WindowListener должен работать, и у вас, вероятно, есть другая проблема в коде, не показанном здесь, и вы захотитечтобы опубликовать sscce для анализа, запуска и изменения.

Редактировать для gpeche
Пожалуйста, ознакомьтесь с этим SSCCE, который показывает, что 3 типапараметры закрытия по умолчанию вызовут слушателя окна:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DialogClosing {
   private static void createAndShowGui() {
      JFrame frame = new JFrame("DialogClosing");

      JPanel mainPanel = new JPanel();
      mainPanel.add(new JButton(new MyAction(frame, JDialog.DISPOSE_ON_CLOSE, "DISPOSE_ON_CLOSE")));
      mainPanel.add(new JButton(new MyAction(frame, JDialog.HIDE_ON_CLOSE, "HIDE_ON_CLOSE")));
      mainPanel.add(new JButton(new MyAction(frame, JDialog.DO_NOTHING_ON_CLOSE, "DO_NOTHING_ON_CLOSE")));

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyAction extends AbstractAction {
   private JDialog dialog;
   private String title;

   public MyAction(JFrame frame, int defaultCloseOp, final String title) {
      super(title);
      dialog = new JDialog(frame, title, false);
      dialog.setDefaultCloseOperation(defaultCloseOp);
      dialog.setPreferredSize(new Dimension(300, 200));
      dialog.pack();
      dialog.addWindowListener(new WindowAdapter() {
         @Override
         public void windowClosed(WindowEvent e) {
            System.out.println(title + " window closed");
         }
         @Override
         public void windowClosing(WindowEvent e) {
            System.out.println(title + " window closing");
         }
      });

      this.title = title;
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
      dialog.setVisible(true);
   }
}
3 голосов
/ 22 октября 2011

Javadoc для WindowListener.windowClosed():

Вызывается, когда окно было закрыто в результате вызова dispose в окне.

А для JDialog.setDefaultCloseOperation():

Устанавливает операцию, которая будет выполняться по умолчанию, когда пользователь инициирует «закрытие» в этом диалоговом окне. Возможные варианты:

  • DO_NOTHING_ON_CLOSE - ничего не делать - требовать, чтобы программа обрабатывала операцию в методе windowClosing зарегистрированного объекта WindowListener.
  • HIDE_ON_CLOSE - автоматически скрывать диалог после вызова любых зарегистрированных объектов WindowListener
  • DISPOSE_ON_CLOSE - автоматически скрывать и удалять диалоговое окно после вызова любых зарегистрированных объектов WindowListener

По умолчанию установлено значение HIDE_ON_CLOSE.

Это говорит о том, что вам следует звонить projectDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); после создания экземпляра FilePathDialog.

2 голосов
/ 22 октября 2011

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

добавление WindowListener к вашему JDialog ( JDialog.DO_NOTHING_ON_CLOSE ), на windowClosing событие, чтобы попытаться запустить ваш код, если заканчивается успешно, затем позвоните dispose(), или setVisible(false)

Я не согласен с вашей идеей, другой обходной путь

создайте только один JDialog (JDialog.DO_NOTHING_ON_CLOSE) с WindowListener и повторно использовать его для другого Action, конечное действие всегда будет setVisible(false), если ваш код заканчивается успешно, затем удалите дочерний элемент (ы) из JDialog, ваш JDialog будетподготовился к другой работе

...