回答:
JFrameのデフォルトの閉じるアクションは、DISPOSE_ON_CLOSE
代わりに " "に設定できますEXIT_ON_CLOSE
(なぜEXIT_ON_CLOSEを使い続けるのかは私を超えています)。
未処理のウィンドウまたはデーモン以外のスレッドがある場合、アプリケーションは終了しません。これはエラーと見なす必要があります(System.exitで解決することは非常に悪い考えです)。
最も一般的な原因は、java.util.Timerとユーザーが作成したカスタムスレッドです。どちらもデーモンに設定するか、明示的に強制終了する必要があります。
すべてのアクティブフレームを確認する場合は、を使用できますFrame.getFrames()
。すべてのウィンドウ/フレームが破棄された場合は、デバッガーを使用して、まだ実行されているデーモン以外のスレッドを確認します。
back
ウィンドウに使用できる場合はどうでしょうか?その後、2番目のウィンドウが閉じDISPOSE_ON_CLOSE
られ、最初のウィンドウがまだ「乱されていない」ためにプログラムが終了しない場合、... を使用せずにそれを解決する方法はありDISPOSE_ON_CLOSE
ますか?
EXIT_ON_CLOSEだと思います
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
before System.exit(0)
は、実際にアプリを終了する前にウィンドウリスナーを作成してクリーニング操作を行うことができるため、優れています。
このウィンドウリスナーを使用すると、次のことを定義できます。
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()を呼び出さずに無関係なスレッドのないプログラムを終了するコードが含まれています。この例をスレッド/リスナー/タイマー/などを使用するアプリケーションに適用するには、actionPerformed()内でWindowEventが手動で開始される前に、終了を要求する(該当する場合は待機する)クリーンアップコードを挿入するだけです。
示されているとおりに実行できるコードをコピー/貼り付けたい場合は、最後に、やや醜いが関係のないメインメソッドが含まれています。
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を存続させることができます。
また、一部のシステムでは、アプリケーションが実際に終了するまでに数秒かかることに気づきました。
他のコメントに応じて、DISPOSE_ON_CLOSEはアプリケーションを適切に終了しないようです。ウィンドウを破壊するだけで、アプリケーションは実行を続けます。アプリケーションを終了する場合は、EXIT_ON_CLOSEを使用します。