Cara menutup JFrame secara pemrograman

251

Apa cara yang benar JFrameuntuk menutup, sama seperti jika pengguna telah menekan Xtombol tutup, atau menekan Alt+ F4(pada Windows)?

Saya memiliki operasi tutup default saya mengatur yang saya inginkan, melalui:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Ia melakukan persis apa yang saya inginkan dengan kontrol yang disebutkan di atas. Pertanyaan ini bukan tentang itu.

Apa yang benar-benar ingin saya lakukan adalah menyebabkan GUI berperilaku dengan cara yang sama seperti menekan Xtombol tutup akan membuatnya berperilaku.

Misalkan saya memperpanjang WindowAdaptordan kemudian menambahkan contoh adaptor saya sebagai pendengar melalui addWindowListener(). Saya ingin melihat urutan yang sama dari panggilan melalui windowDeactivated(), windowClosing()dan windowClosed()seperti yang akan terjadi dengan Xtombol tutup. Tidak begitu banyak merobek jendela seperti mengatakannya untuk merobek sendiri, begitu untuk berbicara.

JustJeff
sumber
10
Apa yang salah dengan menggunakan buang? Begitulah cara saya selalu melakukannya.
job
1
Ya, jFrame.dispose () harus menutup jendela dan membersihkan semuanya?
Tom Neyland
4
Karena membuangnya tidak sama dengan menutup jendela dengan mengklik [x]?
greenoldman
2
Ya pertanyaan yang bagus, saya ingin pengguna mengklik tombol [x]. Saya secara eksplisit menyediakan override undecorated dari JFrame untuk bertindak persis seolah-olah pengguna mengklik tombol [x] yang disediakan oleh OS pada jendela JFrame yang didekorasi khusus OS.
peterk
Bagaimana dengan this.dispatchEvent (wev); alih-alih Toolkit.getDefaultToolkit ... Yang pertama adalah apa yang disarankan jawaban yang diterima.
Jason

Jawaban:

320

Jika Anda ingin GUI berperilaku seperti jika Anda mengklik Xtombol tutup maka Anda harus mengirim acara penutupan jendela ke Window. The ExitActionfrom Closing An Application memungkinkan Anda untuk menambahkan fungsionalitas ini ke item menu atau komponen apa pun yang menggunakan Actions dengan mudah.

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
camickr
sumber
Apakah saya perlu menambahkan this.jframe.addWindowListener (WindowAdapter baru () {@Override public void windowClosing (WindowEvent e) {e.getWindow (). Buang ();}}); sebelum memanggil ini? Atau apakah itu akan menutup jendela juga?
mmm
1
"Cara menutup JFrame secara pemrograman" - Jika JFrame.EXIT_ON_CLOSE tidak disetel, itu tidak akan ditutup. Lagi pula, saya baru saja menunjukkan bahwa mungkin perlu menambahkan jawaban, karena jframe.setDefaultCloseOperation (WindowConstants.DO_NOTHING_ON_CLOSE); tidak akan benar-benar menutupnya dengan memicu acara ini meskipun pengguna biasanya dapat menutup jendela pada X bahkan jika DO_NOTHING_ON_CLOSE disetel, tetapi menjalankan acara ini tidak akan. Lihat perbedaannya?
mmm
3
@momomo, tidak perlu menunjukkan apa pun. Jawaban ini akan melakukan persis seperti yang diminta OP. Ini akan melakukan apa pun yang dilakukan tombol tutup "X". Judul pertanyaan bukanlah pertanyaan. OP secara khusus menyatakan operasi tutup default ditetapkan untuk "keluar", jadi apa yang dilakukan "tidak melakukan apa-apa" tidak relevan karena OP tidak menanyakan hal itu. Hapus semua komentar Anda sehingga Anda tidak membingungkan orang lain yang membaca jawaban ini, karena jawaban itu diberikan untuk langsung menjawab pertanyaan OP, bukan interpretasi Anda tentang judul pertanyaan.
camickr
131
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

Tidak terlalu rumit.

Alex
sumber
38
Tapi itu tidak memanggil pendengar acara.
Bombe
6
Juga, jika ini akan menjadi tombol tutup, proses dibiarkan berjalan di latar belakang juga.
Austin A
1
Tidak jika operasi tutup default adalah pada EXIT_ON_CLOSE atau pendengar tombol melakukan penutupan sumber daya yang diperlukan.
Melinda Green
Itu tidak memanggil pendengar.
Stefan Reich
26

Jika dengan Alt-F4 atau X yang Anda maksud "Keluar Aplikasi Segera Tanpa Regard untuk Apa Windows yang lainnya atau Thread yang Running", maka System.exit(...)akan melakukan persis apa yang Anda inginkan dalam sangat mendadak, brute-force, dan fashion mungkin bermasalah.

Jika dengan Alt-F4 atau X maksud Anda menyembunyikan jendela, maka frame.setVisible(false)adalah bagaimana Anda "menutup" jendela. Jendela akan terus mengkonsumsi sumber daya / memori tetapi dapat dibuat terlihat kembali dengan sangat cepat.

Jika dengan Alt-F4 atau X maksud Anda menyembunyikan jendela dan membuang sumber daya apa pun yang dikonsumsi, maka frame.dispose()adalah bagaimana Anda "menutup" jendela. Jika bingkai adalah jendela yang terlihat terakhir dan tidak ada utas non-daemon lain yang berjalan, program akan keluar. Jika Anda menunjukkan jendela lagi, itu harus menginisialisasi ulang semua sumber daya asli lagi (buffer grafis, pegangan jendela, dll).

dispose()mungkin paling dekat dengan perilaku yang Anda inginkan. Jika aplikasi Anda memiliki beberapa jendela terbuka, apakah Anda ingin Alt-F4 atau X untuk keluar dari aplikasi atau hanya menutup jendela yang aktif?

The Java Swing Tutorial Pendengar Jendela dapat membantu memperjelas hal-hal untuk Anda.

James Schek
sumber
15

Jika Anda telah melakukan ini untuk memastikan pengguna tidak dapat menutup jendela:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Maka Anda harus mengubah pullThePlug()metode Anda menjadi

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); 
}

Saya menemukan ini menjadi satu-satunya cara yang bermain bagus dengan WindowListenerdan JFrame.DO_NOTHING_ON_CLOSE.

Gazihan Alankus
sumber
11

Ini akan menjadi pilihan Anda:

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

Keluar dari proses menjalankan Java sangat mudah, pada dasarnya Anda hanya perlu melakukan dua hal sederhana:

  1. Panggil metode java System.exit(...)di titik berhenti aplikasi. Misalnya, jika aplikasi Anda berbasis bingkai, Anda dapat menambahkan pendengar WindowAdapterdan memanggil System.exit(...)metode di dalamnya windowClosing(WindowEvent e).

Catatan: Anda harus menelepon System.exit(...)jika tidak, program Anda terlibat kesalahan.

  1. Menghindari pengecualian java yang tidak terduga untuk memastikan metode keluar dapat dipanggil selalu. Jika Anda menambahkan System.exit(...)pada titik yang benar, tetapi itu tidak berarti bahwa metode dapat dipanggil selalu, karena pengecualian java yang tidak terduga dapat mencegah metode dari dipanggil.

Ini sangat terkait dengan keterampilan pemrograman Anda.

** Mengikuti adalah contoh paling sederhana ( JFrameberdasarkan) yang menunjukkan kepada Anda cara memanggil metode keluar

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);
   }
}
Jaimin Patel
sumber
7

Tidak hanya untuk menutup JFrame tetapi juga untuk memicu acara WindowListener, coba ini:

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
niranaam
sumber
4

Cara terbaik untuk menutup bingkai Swing secara terprogram adalah dengan membuatnya berperilaku seperti ketika tombol "X" ditekan. Untuk melakukan itu, Anda perlu menerapkan WindowAdapter yang sesuai dengan kebutuhan Anda dan mengatur operasi tutup default frame untuk tidak melakukan apa-apa (DO_NOTHING_ON_CLOSE).

Inisialisasi bingkai Anda seperti ini:

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);
}

Anda dapat menutup frame secara terprogram dengan mengirimkannya acara WINDOW_CLOSING, seperti ini:

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

Ini akan menutup bingkai seperti tombol "X" ditekan.

stjepano
sumber
4

Jika Anda benar-benar tidak ingin aplikasi Anda berakhir saat JFrame ditutup,

gunakan: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

dari pada : setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Berikut sinopsis dari bagaimana solusinya,

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
Harita M
sumber
4

Jawaban ini diberikan oleh Alex dan saya ingin merekomendasikannya. Itu bekerja untuk saya dan hal lain itu mudah dan sangat sederhana.

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object
Humphrey
sumber
1
Apa nilai pengulangan jawaban (dengan +90 suara) dan mengatakan itu berhasil untuk Anda? Mungkin Anda harus memastikan bahwa itu berhasil untuk Anda dalam komentar pada jawaban yang Anda ulangi?
TT.
Saya benar-benar minta maaf untuk itu tetapi kadang-kadang beberapa orang akan merasa lebih percaya diri menggunakan sesuatu yang direkomendasikan
Humphrey
Saya mengerti apa yang Anda katakan, tetapi anggap semua orang yang menggunakan jawaban yang berfungsi menambahkan jawaban yang mengatakan jawaban yang lain bekerja untuk saya. Bagaimana kelihatannya? Ratusan jawaban menjadi pengulangan dari jawaban lain. IMO lebih baik untuk meningkatkan jawaban yang bekerja untuk Anda, mungkin meninggalkan komentar pada jawaban jika itu menambah nilai.
TT.
Terima kasih banyak, saya mengerti maksud Anda dan lain kali itulah yang akan saya lakukan untuk memberikan komentar. Tetapi saya melakukan perbaikan.
Humphrey
2
Tidak, Anda hanya perlu memilih . Jangan tinggalkan komentar, jangan posting jawaban lain.
user202729
3

Contoh ini menunjukkan bagaimana mewujudkan operasi tutup jendela yang dikonfirmasi.

Jendela memiliki adaptor Jendela yang mengalihkan operasi tutup default ke EXIT_ON_CLOSEatau DO_NOTHING_ON_CLOSEtergantung pada jawaban Anda di Windows OptionDialog.

Metode closeWindowdari ConfirmedCloseWindowkebakaran acara jendela dekat dan dapat digunakan di mana saja yaitu sebagai aksi item menu

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));
    }
}
rkd
sumber
3

Berdasarkan jawaban yang telah disediakan di sini, ini adalah cara saya menerapkannya:

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

// frame stuffs here ...

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

JFrame membuat acara tutup dan setelah ditutup, keluar.

Megatron
sumber
2

Anda harus memasukkan panggilan ke dalam antrian pesan AWT sehingga semua waktunya terjadi dengan benar, jika tidak, ia tidak akan mengirimkan urutan kejadian yang benar, terutama dalam program multi-utas. Ketika ini selesai, Anda dapat menangani urutan kejadian yang dihasilkan persis seperti yang Anda lakukan jika pengguna telah mengklik tombol [x] untuk OS yang didekorasi dengan JFrame.

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

Saya sudah mencoba ini, menulis kode Anda sendiri untuk acara 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);
    }
}    

Ini menanyakan pengguna apakah ia ingin keluar dari Frame atau Aplikasi.

r_D
sumber
1

Posting apa yang ada di badan pertanyaan sebagai jawaban CW.

Ingin berbagi hasil, terutama berasal dari mengikuti tautan camickr. Pada dasarnya saya perlu melemparkan WindowEvent.WINDOW_CLOSINGdi antrian acara aplikasi. Berikut ini sinopsis dari bagaimana solusinya

// 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();
Vogel612
sumber
1

Jika Anda tidak ingin aplikasi Anda berhenti ketika JFrame ditutup, gunakan: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

alih-alih: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

Dari dokumentasi:

DO_NOTHING_ON_CLOSE (defined in WindowConstants): Jangan lakukan apa pun; membutuhkan program untuk menangani operasi dalam metode penutupan jendela objek WindowListener terdaftar.

HIDE_ON_CLOSE (defined in WindowConstants): Secara otomatis menyembunyikan bingkai setelah memohon objek WindowListener yang terdaftar.

DISPOSE_ON_CLOSE (defined in WindowConstants): Secara otomatis menyembunyikan dan membuang bingkai setelah memohon objek WindowListener yang terdaftar.

EXIT_ON_CLOSE (defined in JFrame): Keluar dari aplikasi menggunakan metode keluar Sistem. Gunakan ini hanya dalam aplikasi.

mungkin masih berguna: Anda dapat menggunakan setVisible(false)JFrame Anda jika Anda ingin menampilkan frame yang sama lagi. Atau panggil dispose()untuk menghapus semua sumber daya layar asli.

disalin dari Peter Lang

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

Mena Nashaat
sumber
0
 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Itay Maman
sumber
Ini akan bekerja sama dengansetVisible(false) .setVisible(false); .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Abhijeet