JFrame'i programlı olarak kapatma


251

JFrameKapatmak için doğru yol nedir , kullanıcının Xkapat düğmesine basması veya Alt+ F4(Windows'ta) tuşuna basması gibi ?

Benim varsayılan kapatma işlemi aracılığıyla, istediğim şekilde ayarlamak var:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Bahsettiğim kontrollerle tam olarak istediğimi yapıyor. Bu soru bununla ilgili değil.

Gerçekten yapmak istediğim, GUI'nin Xkapat düğmesine basılmasıyla aynı şekilde davranmasına neden olması.

Varsayalım ki WindowAdaptoradaptörün bir örneğini dinleyici olarak ekleyeceğim addWindowListener(). İçinden aramaların aynı sırayı görmek istiyorum windowDeactivated(), windowClosing()ve windowClosed()birlikte oluşacak şekilde Xkapatma düğmesi. Yani pencereyi yırtıp kendini yırtmasını söyleyecek kadar değil.


10
Dispose kullanmanın yanlışlığı nedir? Hep böyle yaptım.

1
Evet, jFrame.dispose () pencereyi kapatmalı ve her şeyi temizlemeli mi?
Tom Neyland

4
Dispose, [x] 'e tıklayarak pencereyi kapatmanın 1: 1 eşdeğeri olmadığı için?
greenoldman

2
Evet iyi bir soru, ben bir kullanıcı tam olarak bir JFrame dekore edilmemiş geçersiz kılma üzerine tedarik bir [x] düğmesine tıklayın istiyorum tam olarak kullanıcı işletim sistemine özgü bir JFrame penceresinde OS verilen [x] düğmesini tıklamış gibi davranmak istiyorum .
peterk

Peki ya bu.dispatchEvent (wev); Toolkit.getDefaultToolkit yerine ... Birincisi kabul edilen cevabın önerisidir.
Jason

Yanıtlar:


320

GUI'nin Xkapat düğmesini tıklatmış gibi davranmasını istiyorsanız, öğesine bir pencere kapatma olayı göndermeniz gerekir Window. ExitActionDan Bir Uygulama Kapanış Bir menü öğesi veya herhangi bir bileşeni kullanır ardından bu işlevleri ekleyebilirsiniz Actionler kolayca.

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

Bunu eklemem gerekiyor mu ?.jframe.addWindowListener (new WindowAdapter () {@Over kamu void penceresini geçersiz kıl bunu çağırmadan önce? Yoksa pencereyi de kapatacak mı?
mmm

1
"Programlı bir JFrame nasıl kapatılır" - JFrame.EXIT_ON_CLOSE ayarlanmamışsa kapanmaz. Her neyse, jframe.setDefaultCloseOperation (WindowConstants.DO_NOTHING_ON_CLOSE) nedeniyle cevaba eklemenin gerekebileceğine işaret ediyordum; DO_NOTHING_ON_CLOSE ayarlanmış olsa bile, kullanıcı normalde X üzerindeki pencereyi kapatabilmesine rağmen bu olayı tetikleyerek gerçekten kapatmaz, ancak bu olayı tetiklemez. Farkı gör?
mmm

3
Momomo, hiçbir şeye işaret etmeye gerek yoktu. Bu cevap OP'nin istediği gibi olacaktır. "X" kapatma düğmesi ne yaparsa yapsın. Sorunun başlığı soru değildir. OP özellikle varsayılan kapatma işleminin "çıkış" olarak ayarlandığını belirtmiştir, bu nedenle OP bu konuda sormadığı için "hiçbir şey yapma" nın ilgisi yoktur. Lütfen tüm yorumlarınızı silin, böylece diğer kişilerin bu yanıtı okumasını karıştırmayın, çünkü sorunun soru başlığı konusundaki yorumunuzu değil, doğrudan OP'nin sorusuna cevap vermek için verildi.
camickr

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

Çok zor değil.


38
Ancak bu olay dinleyicilerini çağırmaz.
Bombe

6
Ayrıca, bu bir kapatma düğmesi olacaksa, işlem arka planda da çalışır.
Austin A

1
Varsayılan kapatma işlemi EXIT_ON_CLOSE konumundaysa veya düğme dinleyici gerekli kaynak kapanışını gerçekleştirmezse değil.
Melinda Green

Dinleyicileri çağırmaz.
Stefan Reich

26

Alt-F4 veya X ile "Diğer Pencerelerin veya İş Parçacıklarının Çalıştığı Ne Olursa Olmadan Uygulamadan Hemen Çık" anlamına geliyorsa, tam olarak istediğinizi çok ani, kaba ve muhtemelen sorunlu bir şekilde System.exit(...)yapacaksınız .

Alt-F4 veya X ile pencereyi gizlemek istiyorsanız, pencereyi frame.setVisible(false)nasıl "kapatırsınız". Pencere kaynakları / belleği tüketmeye devam eder, ancak çok hızlı bir şekilde tekrar görünür hale getirilebilir.

Alt-F4 veya X ile pencereyi gizleyin ve tükettiği kaynakları atın, frame.dispose() istiyorsanız, pencereyi "nasıl" kapattığınız anlamına gelir. Çerçeve son görünür pencere ise ve çalışan başka daemon olmayan iş parçacığı yoksa, program çıkacaktır. Pencereyi tekrar gösterirseniz, tüm yerel kaynakları (grafik arabelleği, pencere tutamaçları vb.) Yeniden başlatması gerekir.

dispose()gerçekten istediğiniz davranışa en yakın olabilir. Uygulamanızda birden fazla pencere açıksa, Alt-F4 veya X'in uygulamadan çıkmasını mı yoksa yalnızca etkin pencereyi kapatmasını mı istiyorsunuz?

Pencere İşleyicilere Java Salıncak Eğitimi sizin için şeye açıklık getireceğini olabilir.


15

Kullanıcının pencereyi kapatamadığından emin olmak için bunu yaptıysanız:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

O zaman pullThePlug()yönteminizi

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

Bunu WindowListenerve ile güzel oynayan tek yol olarak buldum JFrame.DO_NOTHING_ON_CLOSE.


11

İşte seçenekleriniz:

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

8

Java çalıştırma işleminden çıkmak çok kolaydır, temel olarak sadece iki basit şey yapmanız gerekir:

  1. System.exit(...)Uygulamanın çıkış noktasında java yöntemini çağırın . Örneğin, uygulamanız çerçeve tabanlıysa, dinleyici ekleyebilir WindowAdapterve System.exit(...)yöntemini arayabilirsiniz windowClosing(WindowEvent e).

Not: System.exit(...)Aksi takdirde programınız hataya neden olur.

  1. Çıkış yönteminin her zaman çağrılabilmesini sağlamak için beklenmedik java istisnalarından kaçınmak. System.exit(...)Doğru noktada eklerseniz , ancak yöntemin her zaman çağrılabileceği anlamına gelmez, çünkü beklenmeyen java istisnaları yöntemin çağrılmasını engelleyebilir.

Bu, programlama becerilerinizle yakından ilgilidir.

** Aşağıda, JFrameçıkış yöntemini nasıl arayacağınızı gösteren en basit bir örnek ( tabanlı) yer almaktadır

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

Sadece JFrame'i kapatmak için değil, aynı zamanda WindowListener olaylarını da tetiklemek için şunu deneyin:

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

4

Bir Swing çerçevesini programlı olarak kapatmanın en iyi yolu, "X" düğmesine basıldığında olduğu gibi davranmasını sağlamaktır. Bunu yapmak için ihtiyaçlarınıza uyan WindowAdapter uygulamanız ve çerçevenin varsayılan kapatma işlemini hiçbir şey yapmadan ayarlamanız gerekir (DO_NOTHING_ON_CLOSE).

Çerçevenizi şu şekilde başlatın:

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

Çerçeveyi aşağıdaki gibi WINDOW_CLOSING olayı göndererek programlı olarak kapatabilirsiniz:

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

Bu, "X" düğmesine basıldığı gibi çerçeveyi kapatacaktır.


4

Bir JFrame kapatıldığında uygulamanızın gerçekten sona ermesini istemiyorsanız,

kullanın: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

onun yerine : setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

İşte çözümün neye benzediğinin bir özeti,

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

4

Bu cevap Alex tarafından verildi ve bunu tavsiye etmek istiyorum. Benim için işe yaradı ve basit ve çok basit başka bir şey.

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

1
Bir cevabı tekrar etmenin (+90 oyla) ve sizin için işe yaradığını söylemenin değeri nedir? Belki de tekrarladığınız cevap üzerine bir yorumda bunun sizin için çalıştığını doğrulamanız gerekir?
TT.

Bunun için gerçekten çok üzgünüm ama bazen bazı insanlar tavsiye edilen bir şeyi kullanarak kendinden daha emin hissedebilirler
Humphrey

Ne dediğini anlıyorum, ama işe yarayan bir cevap kullanan herkesin, diğer cevabın benim için işe yaradığını söyleyen bir cevap eklediğini varsayalım. Nasıl görünüyor? Yüzlerce cevap diğer cevapların tekrarıdır. IMO, sizin için çalışan cevabı onaylamak daha iyidir, belki herhangi bir değer katarsa ​​cevaba bir yorum bırakın.
TT.

Puanınız için teşekkür ederim ve bir dahaki sefere yorum bırakmak için ne yapacağım. Ama ben oylama yaptım.
Humphrey

2
Hayır, sadece oy kullanmalısınız . Yorum bırakmayın, başka bir cevap göndermeyin.
user202729

3

Bu örnekler, onaylanan pencere kapatma işleminin nasıl gerçekleştirileceğini gösterir.

Pencerede, varsayılan kapatma işlemini , yanıtınızdaki EXIT_ON_CLOSEveyaDO_NOTHING_ON_CLOSEOptionDialog .

Yöntem closeWindowait ConfirmedCloseWindowbir pencereyi kapat olayı harekete ve bir menü öğesinin bir eylem olarak her yerde, yani kullanılabilir

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

Burada daha önce verilen cevaplara dayanarak, bunu uygulama şeklim:

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

// frame stuffs here ...

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

JFrame olayı kapatır ve kapatıldıktan sonra çıkar.


2

Aramayı tüm zamanlamanın doğru şekilde gerçekleşmesi için AWT mesaj kuyruğuna eklemeniz gerekir, aksi takdirde özellikle çok iş parçacıklı bir programda doğru olay dizisini göndermez. Bu yapıldığında, sonuçta ortaya çıkan olay sırasını, kullanıcı OS tarafından dekore edilmiş bir JFrame için [x] düğmesine tıkladığında olduğu gibi işleyebilirsiniz.

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

2

Bunu denedim, formWindowClosing () olayı için kendi kodunuzu yazın .

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

Bu, kullanıcıya Çerçeveden veya Uygulamadan çıkmak isteyip istemediğini sorar.


1

Soru gövdesinde bulunanları CW cevabı olarak yayınlamak.

Sonuçları paylaşmak istedim, esas olarak aşağıdaki camickr'in linkinden elde edildi. Temelde WindowEvent.WINDOW_CLOSINGuygulamanın olay kuyruğuna bir atmak gerekir . İşte çözümün neye benzediğinin bir özeti

// 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

Bir JFrame kapalıyken uygulamanızın sonlandırılmasını istemiyorsanız şunu kullanın: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

yerine: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

Belgelerden:

DO_NOTHING_ON_CLOSE (defined in WindowConstants): Hiçbir şey yapma; Programın, kayıtlı bir WindowListener nesnesinin windowClosing yönteminde çalışmasını gerektirmesi.

HIDE_ON_CLOSE (defined in WindowConstants): Herhangi bir kayıtlı WindowListener nesnesini çağırdıktan sonra çerçeveyi otomatik olarak gizleyin.

DISPOSE_ON_CLOSE (defined in WindowConstants): Herhangi bir kayıtlı WindowListener nesnesini çağırdıktan sonra çerçeveyi otomatik olarak gizleyin ve atın.

EXIT_ON_CLOSE (defined in JFrame): Sistem çıkış yöntemini kullanarak uygulamadan çıkın. Bunu sadece uygulamalarda kullanın.

yine de yararlı olabilir: setVisible(false)Aynı kareyi tekrar görüntülemek istiyorsanız JFrame'inizde kullanabilirsiniz . Aksi takdirde arayındispose() , tüm yerel ekran kaynaklarını kaldırmak için .

Peter Lang'dan kopyalandı

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


0
 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

Bu, setVisible(false) .setVisible(false); .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Abhijeet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.