Есть ли способ закрыть JDialog через код, чтобы прослушиватели событий Window все равно были уведомлены? Я попытался просто установить видимость на false и утилизировать, но, похоже, это не так.
Как закрыть JDialog и получить уведомление слушателей Window Event?
Ответ 1
Закрытие окна (с помощью 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
s, сначала для скрытия, а затем для недействительности, но когда вы спрячете его с помощью setVisible()
, он все еще действителен, поэтому вы не получите недействительности.
Ответ 2
У меня, похоже, нет вашей проблемы. Когда я использую код ниже windowDeactivated() вызывается для setVisible (false) или dispose() и windowClosed ( ) также вызывается для 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);
}
}
Ответ 3
Отправлять событие WindowClosing в окно. Просмотрите пример ExitAction из записи Закрытие приложения.
Ответ 4
Непроданное предложение:
Вы пытались getWindowListeners(), а затем итерации вокруг окна fireClosed() для каждого из WindowListeners?
EDIT: указанное выше предложение неверно. Хранение его для потомства.
Я боюсь, что вызов dialog.dispose() отлично работает для меня в моем простом примере.
Ответ 5
Я хотел запустить событие 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));
Надеюсь, что это поможет кому-то.