Как закрыть JDialog и получать уведомления о прослушивателях событий Windows? - PullRequest
33 голосов
/ 28 августа 2009

Есть ли способ закрыть JDialog через код так, чтобы слушатели событий Window все равно были уведомлены? Я пытался просто установить видимое в false и удалить, но, похоже, ни один из них не делает этого.

Ответы [ 5 ]

48 голосов
/ 31 августа 2009

Закрытие окна (с помощью dispose()) и скрытие его (с помощью setVisible(false)) - это разные операции, которые вызывают разные события, а закрытие его из операционной системы - это еще одна другая операция, которая создает еще одно другое событие.

Все три будут выдавать windowDeactivated, сообщая о потере фокуса окна, но dispose() будет выдавать windowClosed, а при закрытии из ОС сначала выдает windowClosing. Если вы хотите обрабатывать оба этих параметра одинаково, вы можете установить окно, которое будет закрыто:

window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

Как правило, setVisible(false) подразумевает, что вы можете захотеть снова использовать окно, поэтому оно не публикует никаких событий окна (кроме windowDeactivated). Если вы хотите обнаружить скрытие окна, вам нужно использовать ComponentListener;

window.addComponentListener(new ComponentAdapter() {
  @Override
  public void componentHidden(ComponentEvent e) {
    System.out.println("componentHidden()");
  }
})

Обратите внимание, что это в значительной степени будет работать только для явных вызовов setVisible(). Если вам нужно обнаружить скрытие более широко, вы можете использовать HierarchyListener, но это, вероятно, больше проблем, чем стоит.

  window.addHierarchyListener(new HierarchyListener() {
    @Override
      public void hierarchyChanged(HierarchyEvent e) {
        System.out.println("valid: " + window.isValid());
        System.out.println("showing: " + window.isShowing());
      }
  });

Обратите внимание, что когда вы располагаете окном, вы получаете пару HierarchyEvent с, сначала для сокрытия, а затем для аннулирования, но когда вы скрываете его с помощью setVisible(), оно все еще действует, поэтому вы не получите недействительности.

3 голосов
/ 28 августа 2009

Кажется, у меня нет твоей проблемы. Когда я использую приведенный ниже код, windowDeactivation () вызывается для setVisible (false) или dispose () и windowClosed () is также вызывается для dispose ().

ClosingDialog.java:

public class ClosingDialog extends JDialog {
    public ClosingDialog(Frame owner, String title, boolean modal) {
        super(owner, title, modal);
        JPanel contentPanel = (JPanel) this.getContentPane();

        JButton setVisButton = new JButton("setVisible( false )");
        setVisButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClosingDialog.this.setVisible(false);
            }
        });

        JButton disposeButton = new JButton("dispose()");
        disposeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ClosingDialog.this.dispose();
            }
        });

        contentPanel.setLayout(new FlowLayout());

        contentPanel.add(setVisButton);
        contentPanel.add(disposeButton);

        this.addWindowListener(new WindowListener() {
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }

            public void windowClosed(WindowEvent e) {
                System.out.println("windowClosed");
            }

            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
            }

            public void windowDeactivated(WindowEvent e) {
                System.out.println("windowDeactivated");
            }

            public void windowDeiconified(WindowEvent e) {
                System.out.println("windowDeiconified");
            }

            public void windowIconified(WindowEvent e) {
                System.out.println("windowIconified");
            }

            public void windowOpened(WindowEvent e) {
                System.out.println("windowOpened");
            }
        });

        this.setSize(300, 300);
    }
}
1 голос
/ 28 августа 2009

Отправка события windowClosing в окно. Посмотрите пример ExitAction из записи Закрытие приложения .

0 голосов
/ 01 июня 2013

Я хотел запустить событие windowClosing из кода (как если бы пользователь нажал X), потому что у меня есть дополнительная кнопка закрытия в JDialog и я хочу тот же WindowListener (который я реализовал с использованием WindowAdapter ) для запуска при нажатии X и при нажатии кнопки. Запуск dispose() запускает только windowClosed, а не windowClosing, и я хочу, чтобы сообщение отображалось до , когда окно закрыто, для подтверждения. Мне также не удалось запустить windowClosing по методу JDialog processWindowEvent, поскольку он защищен.

Вот как я все это заработал:

WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0];
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING));

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 28 августа 2009

Непроверенное предложение:

Вы пробовали getWindowListeners (), а затем перебирали для запуска windowClosed () для каждого из WindowListeners?

РЕДАКТИРОВАТЬ: приведенное выше предложение неверно. Хранить его для потомков.

Боюсь, что в моем простом примере вызов dialog.dispose () прекрасно работает для меня.

...