답변:
JFrame 기본 닫기 작업을 DISPOSE_ON_CLOSE
대신 " " 로 설정할 수 있습니다 EXIT_ON_CLOSE
(사람들이 EXIT_ON_CLOSE를 계속 사용하는 이유는 저 밖에 없습니다).
처리되지 않은 창이나 데몬이 아닌 스레드가있는 경우 응용 프로그램이 종료되지 않습니다. 이것은 오류로 간주되어야합니다 (System.exit로 해결하는 것은 매우 나쁜 생각입니다).
가장 일반적인 원인은 java.util.Timer와 사용자가 만든 사용자 지정 스레드입니다. 둘 다 daemon으로 설정하거나 명시 적으로 종료해야합니다.
모든 활성 프레임을 확인하려면을 사용할 수 있습니다 Frame.getFrames()
. 모든 Windows / 프레임이 삭제 된 경우 디버거를 사용하여 아직 실행중인 비 데몬 스레드를 확인합니다.
back
창에 사용할 수 있다면 어떨까요? 두 번째 창이 닫히고 DISPOSE_ON_CLOSE
첫 번째 창이 여전히 "분할되지 않은"상태이기 때문에 프로그램이 종료되지 않는 경우 ... 사용 하지 않고 해결할 수있는 방법이 DISPOSE_ON_CLOSE
있습니까?
EXIT_ON_CLOSE 인 것 같아요
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
실제로 앱을 떠나기 전에 몇 가지 정리 작업을 수행 System.exit(0)
하는 Window Listener 를 작성할 수 있기 때문에 before 가 더 좋습니다 .
이 창 리스너를 사용하면 다음을 정의 할 수 있습니다.
public void windowClosing(WindowEvent e) {
displayMessage("WindowListener method called: windowClosing.");
//A pause so user can see the message before
//the window actually closes.
ActionListener task = new ActionListener() {
boolean alreadyDisposed = false;
public void actionPerformed(ActionEvent e) {
if (frame.isDisplayable()) {
alreadyDisposed = true;
frame.dispose();
}
}
};
Timer timer = new Timer(500, task); //fire every half second
timer.setInitialDelay(2000); //first delay 2 seconds
timer.setRepeats(false);
timer.start();
}
public void windowClosed(WindowEvent e) {
//This will only be seen on standard output.
displayMessage("WindowListener method called: windowClosed.");
}
시험:
System.exit(0);
조잡하지만 효과적입니다.
안전한 방법은 다음과 같습니다.
private JButton btnExit;
...
btnExit = new JButton("Quit");
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
Container frame = btnExit.getParent();
do
frame = frame.getParent();
while (!(frame instanceof JFrame));
((JFrame) frame).dispose();
}
});
Frame
정확히 ... 클래스의 이름처럼 대문자로를
다음 프로그램에는 System.exit ()를 명시 적으로 호출하지 않고 외부 스레드가없는 프로그램을 종료하는 코드가 포함되어 있습니다. 이 예제를 스레드 / 수신기 / 타이머 등을 사용하는 응용 프로그램에 적용하려면 WindowEvent가 actionPerformed () 내에서 수동으로 시작되기 전에 종료를 요청 (해당되는 경우 대기)하는 정리 코드 만 삽입하면됩니다.
표시된대로 정확하게 실행할 수있는 코드를 복사 / 붙여 넣기하려는 사람들을 위해 약간 못 생겼지 만 관련이없는 주요 방법이 끝에 포함됩니다.
public class CloseExample extends JFrame implements ActionListener {
private JButton turnOffButton;
private void addStuff() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
turnOffButton = new JButton("Exit");
turnOffButton.addActionListener(this);
this.add(turnOffButton);
}
public void actionPerformed(ActionEvent quitEvent) {
/* Iterate through and close all timers, threads, etc here */
this.processWindowEvent(
new WindowEvent(
this, WindowEvent.WINDOW_CLOSING));
}
public CloseExample() {
super("Close Me!");
addStuff();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
CloseExample cTW = new CloseExample();
cTW.setSize(200, 100);
cTW.setLocation(300,300);
cTW.setVisible(true);
}
});
}
}
사용자가 닫기 버튼을 클릭하지 않았더라도 응용 프로그램을 닫고 싶습니다. 필요에 더 적합한 addWindowListener () 또는 enableEvents ()를 사용하여 WindowEvents를 등록해야합니다.
그런 다음 processWindowEvent ()를 호출하여 이벤트를 호출 할 수 있습니다. 다음은 JFrame을 만들고 5 초간 기다린 후 사용자 상호 작용없이 JFrame을 닫는 샘플 코드입니다.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClosingFrame extends JFrame implements WindowListener{
public ClosingFrame(){
super("A Frame");
setSize(400, 400);
//in case the user closes the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//enables Window Events on this Component
this.addWindowListener(this);
//start a timer
Thread t = new Timer();
t.start();
}
public void windowOpened(WindowEvent e){}
public void windowClosing(WindowEvent e){}
//the event that we are interested in
public void windowClosed(WindowEvent e){
System.exit(0);
}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
//a simple timer
class Timer extends Thread{
int time = 10;
public void run(){
while(time-- > 0){
System.out.println("Still Waiting:" + time);
try{
sleep(500);
}catch(InterruptedException e){}
}
System.out.println("About to close");
//close the frame
ClosingFrame.this.processWindowEvent(
new WindowEvent(
ClosingFrame.this, WindowEvent.WINDOW_CLOSED));
}
}
//instantiate the Frame
public static void main(String args[]){
new ClosingFrame();
}
}
보시다시피 processWindowEvent () 메서드는 응용 프로그램을 닫기 전에 필요한 경우 코드를 정리할 기회가있는 곳에서 WindowClosed 이벤트를 발생시킵니다.
Oracle 문서를 살펴보십시오 .
JDK 1.4부터 다음과 같은 경우 응용 프로그램이 종료됩니다.
코너 케이스 :
문서에는 일부 패키지가 릴리스하지 않고 표시 가능한 구성 요소를 생성한다고 명시되어 있습니다. Toolkit.getDefaultToolkit ()을 호출하는 프로그램은 종료되지 않습니다. 예를 들면 다른 것들 중입니다.
또한 다른 프로세스는 어떤 이유로 든 이벤트를 네이티브 이벤트 큐로 보낼 때 AWT를 활성 상태로 유지할 수 있습니다.
또한 일부 시스템에서는 응용 프로그램이 실제로 종료되기까지 몇 초가 걸립니다.