Какое правильное действие следует предпринять при закрытии окон в java / swing?
Я только что написал этот тестовый код в своем классе CustomUIPanel:
public static void main(String[] args) {
final JDialog dialog = CustomUIPanel.createDialog(null,
CustomUIPanel.selectFile());
dialog.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
он работает правильно, если CustomUIPanel.main()
является точкой входа программы, но это заставляет меня задуматься: что, если другой класс называется CustomUIPanel.main()
для тестирования? Тогда мой призыв к System.exit(0)
- это неправильно.
есть ли способ сообщить потоку отправки событий Swing, чтобы выйти автоматически, если нет окон верхнего уровня?
если нет, то что правильно для JDialog/JFrame делать при закрытии, если цель состоит в том, чтобы программа вышла, когда все окна верхнего уровня закрыты?
6 ответов
можно использовать setDefaultCloseOperation()
метод JDialog
, С указанием DISPOSE_ON_CLOSE
:
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
см. также 12.8 Выход Из Программы.
Addendum: включая полезный ответ @camickr, этот пример завершается, когда либо окно закрыто, либо кнопка закрытия нажата.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
/** @see http://stackoverflow.com/questions/5540354 */
public class DialogClose extends JDialog {
public DialogClose() {
this.setLayout(new GridLayout(0, 1));
this.add(new JLabel("Dialog close test.", JLabel.CENTER));
this.add(new JButton(new AbstractAction("Close") {
@Override
public void actionPerformed(ActionEvent e) {
DialogClose.this.setVisible(false);
DialogClose.this.dispatchEvent(new WindowEvent(
DialogClose.this, WindowEvent.WINDOW_CLOSING));
}
}));
}
private void display() {
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new DialogClose().display();
}
});
}
}
Не уверен в использовании JDialog.
но при использовании JFrame вы должны использовать frame.распоряжаться.)( Если кадр является последним открытым кадром, то VM выйдет.
Примечание. диалог не имеет опции EXIT_ON_CLOSE, так как он обычно не должен выходить из виртуальной машины.
при закрытии диалога вы всегда можете получить Родительский фрейм диалогов. Затем вы можете отправить событие в кадр, чтобы сказать ему закрыть себя. Что-то вроде:
WindowEvent windowClosing = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
//Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowClosing);
frame.dispatchEvent(windowClosing);
Ну
вместо этого вы можете использовать JFrame. JDialog предполагается использовать как всплывающее окно приложения, которое работает в JFrame, чтобы привлечь внимание пользователей и приостановить основное приложение. Если JFrame закрыт, Вы можете вызвать System.выход(0)
в диалоговом окне getParent()
метод, который я предполагаю, имеет значение null в вашем случае здесь CustomUIPanel.createDialog(null,
вы можете использовать это, чтобы выйти условно.