JFrameをプログラムで閉じる方法


251

JFrameユーザーがX閉じるボタンを押す、またはAlt+ F4(Windows)を押した場合と同じように、を閉じる正しい方法は何ですか?

デフォルトのクローズ操作を希望どおりに設定します。

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

前述のコントロールで私が望んでいることを正確に実行します。この質問はそれについてではありません。

私が本当にやりたいことは、X閉じるボタンを押すとGUIが動作するのと同じようにGUIを動作させることです。

を拡張してWindowAdaptorから、アダプタのインスタンスをを介してリスナーとして追加するとしますaddWindowListener()。私は経由の通話の同じシーケンスを見たいwindowDeactivated()windowClosing()windowClosed()して起こるとX閉じるボタン。ウィンドウを引き裂くのは、いわばそれ自体を引き裂くように言うほどではありません。


10
破棄の使用の何が問題になっていますか?それは私がいつもそれをした方法です。
ジョブ

1
ええ、jFrame.dispose()はウィンドウを閉じてすべてをクリーンアップする必要がありますか?
トムネイランド

4
破棄は、[x]をクリックしてウィンドウを閉じることと1:1で同等ではないためですか?
greenoldman 2011

2
はいいい質問は、私が欲しい、私は明示的に行動したJFrameの装飾のないオーバーライドに供給し、[X]ボタンをユーザーがクリックまさにユーザーがOS上でクリックしたかのようにJFrameのウィンドウ装飾されたOSの特定の[×]ボタンを供給しました。
2012

this.dispatchEvent(wev);はどうですか。Toolkit.getDefaultToolkitの代わりに...前者は、受け入れられた答えが示唆するものです。
Jason

回答:


320

GUIをX閉じるボタンをクリックしたかのように動作させたい場合は、ウィンドウを閉じるイベントをにディスパッチする必要がありますWindowアンアプリケーションを閉じるには、メニュー項目または任意のコンポーネント使用していることに、この機能を追加することを可能にするのに容易。ExitActionAction

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

this.jframe.addWindowListener(new WindowAdapter(){@Override public void windowClosing(WindowEvent e){e.getWindow()。dispose();}});を追加する必要がありますか?これを呼び出す前に?それともウィンドウを閉じますか?
mmm

1
「JFrameをプログラムで閉じる方法」-JFrame.EXIT_ON_CLOSEが設定されていない場合、閉じません。とにかく、jframe.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);なので、答えに追加する必要があるかもしれないことを指摘していました。DO_NOTHING_ON_CLOSEが設定されていても、ユーザーは通常Xでウィンドウを閉じることができますが、このイベントをトリガーして実際に閉じることはありませんが、このイベントは発生しません。違いを見ます?
mmm '26 / 07/26

3
@momomo、何も指摘する必要はありませんでした。この回答は、OPが要求したとおりに実行されます。「X」の閉じるボタンと同じように動作します。質問のタイトルは質問ではありません。OPは、デフォルトのクローズ操作が「exit」に設定されていることを明確に述べているため、OPはそれを要求していなかったので、「何もしない」ことは関係ありません。回答はOPの質問に直接回答するためのものであり、質問の見出しの解釈ではないため、この回答を読んでいる他の人を混乱させないように、すべてのコメントを削除してください。
camickr 2017

131
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

あまりトリッキーではありません。


38
しかし、それはイベントリスナーを呼び出しません。
ボンベ、

6
また、これが閉じるボタンである場合、プロセスはバックグラウンドでも実行されたままになります。
オースティンA

1
デフォルトのクローズ操作がEXIT_ON_CLOSEである場合、またはボタンリスナーが必要なリソースのクローズを実行する場合は除きます。
Melinda Green

リスナーを呼び出しません。
ステファンライヒ

26

Altキーを押しながらF4またはXであなたが意味する場合は、その後、「どのようなその他のWindowsまたはスレッドが実行されているにかかわらず、すぐにアプリケーションを終了します」System.exit(...)行いますまさにあなたは非常に突然、強引に欲しいもの、そしておそらく問題のファッション。

Alt-F4またはXでウィンドウを非表示にする場合は、ウィンドウframe.setVisible(false)を「閉じる」方法です。ウィンドウは引き続きリソース/メモリを消費しますが、非常にすばやく再び表示できます。

Alt-F4またはXでウィンドウを非表示にして、消費しているリソースを破棄する場合はframe.dispose()、ウィンドウを「閉じる」方法です。フレームが最後に表示されていたウィンドウであり、デーモン以外のスレッドが実行されていない場合、プログラムは終了します。ウィンドウを再度表示する場合、すべてのネイティブリソース(グラフィックバッファー、ウィンドウハンドルなど)を再度初期化する必要があります。

dispose()あなたが本当に望む行動に最も近いかもしれません。アプリで複数のウィンドウが開いている場合、Alt-F4またはXでアプリを終了しますか、それともアクティブウィンドウを閉じますか?

ウィンドウリスナー上のJava Swingのチュートリアルでは、あなたのために物事を明確に役立つかもしれません。


15

ユーザーがウィンドウを閉じないようにするためにこれを行った場合:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

次に、pullThePlug()メソッドを次のように変更する必要があります

public void pullThePlug() {
    // this will make sure WindowListener.windowClosing() et al. will be called.
    WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);

    // this will hide and dispose the frame, so that the application quits by
    // itself if there is nothing else around. 
    setVisible(false);
    dispose();
    // if you have other similar frames around, you should dispose them, too.

    // finally, call this to really exit. 
    // i/o libraries such as WiiRemoteJ need this. 
    // also, this is what swing does for JFrame.EXIT_ON_CLOSE
    System.exit(0); 
}

私はこれはと素敵を果たしている唯一の方法であることが判明WindowListenerしてJFrame.DO_NOTHING_ON_CLOSE


11

ここにあなたのオプションがあります:

System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window

8

Java実行プロセスを終了するのは非常に簡単です。基本的に、次の2つのことを行うだけです。

  1. System.exit(...)アプリケーションの終了点でjavaメソッドを呼び出します。たとえば、アプリケーションがフレームベースの場合、リスナーWindowAdapterを追加しSystem.exit(...)て、そのメソッド内で呼び出すことができますwindowClosing(WindowEvent e)

注:呼び出す必要があります。System.exit(...)そうしないと、プログラムにエラーが発生します。

  1. 予期しないJava例外を回避して、exitメソッドを常に呼び出せるようにします。System.exit(...)正しいポイントで追加した場合、予期しないjava例外がメソッドの呼び出しを妨げる可能性があるため、メソッドを常に呼び出すことができるとは限りません。

これはプログラミングのスキルに強く関係しています。

**以下は、JFrameexitメソッドを呼び出す方法を示す最も簡単なサンプル(ベース)です

import java.awt.event.*;
import javax.swing.*;

public class ExitApp extends JFrame
{
   public ExitApp()
   {
      addWindowListener(new WindowAdapter()
      {
         public void windowClosing(WindowEvent e)
         {
           dispose();
           System.exit(0); //calling the method is a must
         }
      });
   }

   public static void main(String[] args)
   {
      ExitApp app=new ExitApp();
      app.setBounds(133,100,532,400);
      app.setVisible(true);
   }
}

7

JFrameを閉じるだけでなく、WindowListenerイベントをトリガーするには、次のことを試してください。

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

4

プログラムでSwingフレームを閉じる最良の方法は、「X」ボタンが押されたときのように動作させることです。そのためには、ニーズに合ったWindowAdapterを実装し、フレームのデフォルトのクローズ操作を何もしないように設定する必要があります(DO_NOTHING_ON_CLOSE)。

次のようにフレームを初期化します。

private WindowAdapter windowAdapter = null;

private void initFrame() {

    this.windowAdapter = new WindowAdapter() {
        // WINDOW_CLOSING event handler
        @Override
        public void windowClosing(WindowEvent e) {
            super.windowClosing(e);
            // You can still stop closing if you want to
            int res = JOptionPane.showConfirmDialog(ClosableFrame.this, "Are you sure you want to close?", "Close?", JOptionPane.YES_NO_OPTION);
            if ( res == 0 ) {
                // dispose method issues the WINDOW_CLOSED event
                ClosableFrame.this.dispose();
            }
        }

        // WINDOW_CLOSED event handler
        @Override
        public void windowClosed(WindowEvent e) {
            super.windowClosed(e);
            // Close application if you want to with System.exit(0)
            // but don't forget to dispose of all resources 
            // like child frames, threads, ...
            // System.exit(0);
        }
    };

    // when you press "X" the WINDOW_CLOSING event is called but that is it
    // nothing else happens
    this.setDefaultCloseOperation(ClosableFrame.DO_NOTHING_ON_CLOSE);
    // don't forget this
    this.addWindowListener(this.windowAdapter);
}

次のように、WINDOW_CLOSINGイベントを送信して、プログラムでフレームを閉じることができます。

WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);

これは、「X」ボタンが押されたようにフレームを閉じます。


4

JFrameが閉じられたときにアプリケーションを終了させたくない場合は、

使用する : setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

の代わりに : setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

ソリューションの概要は次のとおりです。

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

4

この答えはアレックスによって与えられました、そして私はそれをお勧めしたいと思います。それは私にとってはうまくいきました、そしてもう一つはそれが簡単でとてもシンプルです。

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

1
回答を(+90票で)繰り返し、それがうまくいったことを伝えることの価値は何ですか?おそらく、あなたが繰り返した答えについてのコメントでそれがあなたのためにうまくいったことを確認するべきですか?
TT。

本当に申し訳ありませんが、推奨されるものを使用することに自信を持つ人もいます
Humphrey

私はあなたの言っていることを理解していますが、うまくいった答えを使用したすべての人が、私のために他の答えがうまくいったという答えを追加するとします。どうですか?何百もの答えが他の答えの繰り返しです。IMOうまくいった回答に賛成票を投じるほうがよいでしょう。価値がある場合は、回答にコメントを残してください。
TT。

どうもありがとうございました。次回はコメントを残すためにそれを行います。しかし、私は賛成票を投じました。
ハンフリー

2
いいえ、投票するだけです。コメントを残したり、別の回答を投稿したりしないでください。
user202729

3

この例は、確認されたウィンドウクローズ操作を実現する方法を示しています。

ウィンドウにはウィンドウアダプターがあり、デフォルトのクローズ操作をでの回答に切り替えるEXIT_ON_CLOSEDO_NOTHING_ON_CLOSE、回答に依存しますOptionDialog

のメソッドcloseWindowは、ConfirmedCloseWindowウィンドウを閉じるイベントを発生させ、メニュー項目のアクションとして、どこでも使用できます。

public class WindowConfirmedCloseAdapter extends WindowAdapter {

    public void windowClosing(WindowEvent e) {

        Object options[] = {"Yes", "No"};

        int close = JOptionPane.showOptionDialog(e.getComponent(),
                "Really want to close this application?\n", "Attention",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.INFORMATION_MESSAGE,
                null,
                options,
                null);

        if(close == JOptionPane.YES_OPTION) {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.EXIT_ON_CLOSE);
        } else {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.DO_NOTHING_ON_CLOSE);
        }
    }
}

public class ConfirmedCloseWindow extends JFrame {

    public ConfirmedCloseWindow() {

        addWindowListener(new WindowConfirmedCloseAdapter());
    }

    private void closeWindow() {
        processWindowEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
    }
}

3

ここですでに提供されている回答に基づいて、これは私がそれを実装した方法です:

JFrame frame= new JFrame()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// frame stuffs here ...

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

JFrameはイベントを閉じて閉じ、終了すると終了します。


2

すべてのタイミングが正しく行われるように、呼び出しをAWTメッセージキューに挿入する必要があります。そうしないと、特にマルチスレッドプログラムでは、正しいイベントシーケンスがディスパッチされません。これが完了すると、ユーザーがOSで装飾されたJFrameの[x]ボタンをクリックした場合と同様に、結果のイベントシーケンスを処理できます。

public void closeWindow()
{
    if(awtWindow_ != null) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
            }
        });
    }
}

2

私はこれを試しました、formWindowClosing()イベント用の独自のコードを書きます。

 private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
    int selectedOption = JOptionPane.showConfirmDialog(null,
            "Do you want to exit?",
            "FrameToClose",
            JOptionPane.YES_NO_OPTION);
    if (selectedOption == JOptionPane.YES_OPTION) {
        setVisible(false);
        dispose();
    } else {
        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
    }
}    

これにより、フレームまたはアプリケーションを終了するかどうかをユーザーに尋ねます。


1

質問の本文にあったものをCW回答として投稿します。

主にcamickrのリンクから派生した結果を共有したかった。基本的にWindowEvent.WINDOW_CLOSING、アプリケーションのイベントキューにをスローする必要があります。ソリューションの概要は次のとおりです

// closing down the window makes sense as a method, so here are
// the salient parts of what happens with the JFrame extending class ..

    public class FooWindow extends JFrame {
        public FooWindow() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(5, 5, 400, 300);  // yeah yeah, this is an example ;P
            setVisible(true);
        }
        public void pullThePlug() {
                WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
        }
    }

// Here's how that would be employed from elsewhere -

    // someplace the window gets created ..
    FooWindow fooey = new FooWindow();
    ...
    // and someplace else, you can close it thusly
    fooey.pullThePlug();

1

JFrameが閉じられたときにアプリケーションを終了させたくない場合は、次を使用します:setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)

代わりに:setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

ドキュメントから:

DO_NOTHING_ON_CLOSE (defined in WindowConstants):何もしないでください。登録されたWindowListenerオブジェクトのwindowClosingメソッドでの操作をプログラムが処理する必要があります。

HIDE_ON_CLOSE (defined in WindowConstants):登録されたWindowListenerオブジェクトを呼び出した後、フレームを自動的に非表示にします。

DISPOSE_ON_CLOSE (defined in WindowConstants):登録済みのWindowListenerオブジェクトを呼び出した後、フレームを自動的に非表示にして破棄します。

EXIT_ON_CLOSE (defined in JFrame):システム終了メソッドを使用してアプリケーションを終了します。これはアプリケーションでのみ使用してください。

setVisible(false)同じフレームを再度表示したい場合は、JFrameで使用できます。それ以外の場合は、呼び出しdispose()てネイティブ画面リソースをすべて削除します。

Peter Langからコピー

https://stackoverflow.com/a/1944474/3782247


0
 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

これは次と組み合わせて機能しますsetVisible(false) .setVisible(false); .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Abhijeet
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.