코드에서 Java Swing 애플리케이션을 닫는 방법
코드에서 Swing 애플리케이션을 종료하는 적절한 방법은 무엇이며 함정은 무엇입니까?
타이머가 실행 된 후 자동으로 애플리케이션을 닫으려고했습니다. 그러나를 호출 dispose()
하는 것만으로 JFrame
는 트릭 이 발생 하지 않았습니다. 창이 사라졌지 만 응용 프로그램이 종료되지 않았습니다. 그러나 닫기 버튼으로 창을 닫으면 응용 프로그램이 종료됩니다. 어떻게해야합니까?
JFrame 기본 닫기 작업을 DISPOSE_ON_CLOSE
대신 " " 로 설정할 수 있습니다 EXIT_ON_CLOSE
(사람들이 EXIT_ON_CLOSE를 계속 사용하는 이유는 저 밖에 없습니다).
처리되지 않은 창이나 데몬이 아닌 스레드가있는 경우 응용 프로그램이 종료되지 않습니다. 이것은 오류로 간주되어야합니다 (System.exit로 해결하는 것은 매우 나쁜 생각입니다).
가장 일반적인 원인은 java.util.Timer와 사용자가 만든 사용자 지정 스레드입니다. 둘 다 daemon으로 설정하거나 명시 적으로 종료해야합니다.
모든 활성 프레임을 확인하려면을 사용할 수 있습니다 Frame.getFrames()
. 모든 Windows / 프레임이 삭제 된 경우 디버거를 사용하여 아직 실행중인 비 데몬 스레드를 확인합니다.
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();
}
});
The following program includes code that will terminate a program lacking extraneous threads without explicitly calling System.exit(). In order to apply this example to applications using threads/listeners/timers/etc, one need only insert cleanup code requesting (and, if applicable, awaiting) their termination before the WindowEvent is manually initiated within actionPerformed().
For those who wish to copy/paste code capable of running exactly as shown, a slightly-ugly but otherwise irrelevant main method is included at the end.
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);
}
});
}
}
If I understand you correctly you want to close the application even if the user did not click on the close button. You will need to register WindowEvents maybe with addWindowListener() or enableEvents() whichever suits your needs better.
You can then invoke the event with a call to processWindowEvent(). Here is a sample code that will create a JFrame, wait 5 seconds and close the JFrame without user interaction.
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();
}
}
As you can see, the processWindowEvent() method causes the WindowClosed event to be fired where you have an oportunity to do some clean up code if you require before closing the application.
Take a look at the Oracle Documentation.
Starting from JDK 1.4 an Application terminates if:
- There are no displayable AWT or Swing components.
- There are no native events in the native event queue.
- There are no AWT events in java EventQueues.
Cornercases:
The document states that some packages create displayable components without releasing them.A program which calls Toolkit.getDefaultToolkit() won't terminate. is among others given as an example.
Also other Processes can keep AWT alive when they, for what ever reason, are sending events into the native event queue.
Also I noticed that on some Systems it takes a coupple of seconds before the Application actually terminates.
I think, the idea is here the WindowListener - you can add any code there that you'd like to run before the thing shuts down
In response to other comments, DISPOSE_ON_CLOSE does not seem to properly exit the application - it only destroys the window, but the application will continue running. If you want to terminate the application use EXIT_ON_CLOSE.
참고URL : https://stackoverflow.com/questions/258099/how-to-close-a-java-swing-application-from-the-code
'developer tip' 카테고리의 다른 글
jQuery 위치 href (0) | 2020.09.05 |
---|---|
pg_dump를 올바르게 인증하려면 어떻게해야합니까? (0) | 2020.09.05 |
Regex 마지막 발생? (0) | 2020.09.05 |
React에서 Esc Key Press를 감지하는 방법 및 처리 방법 (0) | 2020.09.05 |
스위치 케이스의 변수 범위 (0) | 2020.09.05 |