سؤال

ما هي الطريقة الصحيحة للحصول على JFrame لإغلاق كما إذا كان المستخدم قد ضرب X زر إغلاق ، أو الضغط Alt+F4 (في Windows)?

لدي الافتراضي إغلاق عملية تعيين الطريقة التي أريد ، عن طريق:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

يفعل بالضبط ما أريد مع الضوابط المذكورة آنفا.هذا السؤال ليس حول ذلك.

ما كنت حقا تريد القيام به هو سبب GUI تتصرف بنفس الطريقة الضغط X زر إغلاق شأنه أن يؤدي إلى التصرف.

لنفترض انني تمديد WindowAdaptor ثم إضافة مثيل من محول كمستمع عبر addWindowListener().وأود أن نرى نفس تسلسل من المكالمات من خلال windowDeactivated(), windowClosing(), ، windowClosed() كما يمكن أن يحدث مع X زر إغلاق.وليس ذلك بكثير تمزيق النافذة كما تقول المسيل للدموع نفسها ، إذا جاز التعبير.

هل كانت مفيدة؟

المحلول

إذا كنت ترغب في واجهة المستخدم الرسومية لتتصرف كما لو قمت بالنقر فوق الزر إغلاق X ثم تحتاج إلى إيفاد الحدث إغلاق نافذة إلى Window. وExitAction من إغلاق التطبيق يسمح لك بإضافة هذه الوظيفة لعنصر قائمة أو أي مكون يستخدم Actions بسهولة.

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

نصائح أخرى

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

وليس صعبة للغاية.

وإذا كان عن طريق الضغط على مفتاح Alt F4 أو X تعني "الخروج من التطبيق مباشرة دون اعتبار لماذا Windows أو المواضيع الأخرى وتشغيل"، ثم System.exit(...) ستفعل <م> بالضبط ما تريد في مفاجئا جدا، الغاشمة -Force، والأزياء ربما مشكلة.

وإذا كان عن طريق الضغط على مفتاح Alt F4 أو X تقصد إخفاء النافذة، ثم frame.setVisible(false) هي الطريقة التي "وثيقة" الإطار. وسوف تستمر نافذة لتستهلك موارد / الذاكرة، ولكن يمكن أن تكون مرئيا مرة أخرى بسرعة كبيرة.

وإذا كان عن طريق الضغط على مفتاح Alt F4 أو X تقصد إخفاء النافذة والتخلص من أي الموارد التي تستهلك، ثم frame.dispose() هي الطريقة التي "وثيقة" الإطار. إذا كان إطار نافذة مرئية الماضي، وهناك أي مواضيع أخرى غير الشيطان تشغيل، سيقوم البرنامج خروج. إذا كنت تظهر النافذة مرة أخرى، وسوف تضطر إلى إعادة تهيئة كافة الموارد المحلية مرة أخرى (عازلة الرسومات، مقابض النوافذ، الخ).

وdispose() قد يكون الأقرب إلى السلوك الذي تريده حقا. إذا التطبيق لديه العديد من النوافذ المفتوحة، هل تريد الضغط على مفتاح Alt F4 أو X لإنهاء التطبيق أو إغلاق فقط الإطار النشط؟

جافا سوينغ البرنامج التعليمي على المستمعين النافذة قد مساعدة في توضيح الامور بالنسبة لك.

إذا كنت قد فعلت ذلك للتأكد من أن المستخدم لا يمكن إغلاق النافذة:

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.

وهنا سيكون خياراتك:

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

تخرج من جافا يعمل عملية سهلة جدا ، أساسا ما عليك القيام به اثنين فقط من الأشياء البسيطة:

  1. دعوة طريقة جافا System.exit(...) في التطبيق الإقلاع نقطة.على سبيل المثال, إذا كان التطبيق الخاص بك هو الإطار القائم ، يمكنك إضافة المستمع WindowAdapter و الاتصال System.exit(...) داخل الطريقة windowClosing(WindowEvent e).

ملاحظة:يجب استدعاء System.exit(...) وإلا البرنامج هو خطأ المعنية.

  1. تجنب غير متوقعة جافا الاستثناءات للتأكد من خروج الطريقة يمكن أن يسمى دائما.إذا قمت بإضافة System.exit(...) في حق ولكن هذا لا يعني أن الطريقة يمكن أن يسمى دائما ، لأن غير متوقعة جافا الاستثناءات قد منع طريقة من كان يسمى.

هذا يرتبط بشدة مهارات البرمجة الخاصة بك.

** وفيما يلي أبسط العينة (JFrame على أساس) الذي يظهر لك كيفية استدعاء خروج الطريقة

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

وليس فقط لإغلاق JFrame ولكن أيضا لتحريك الأحداث WindowListener، حاول هذا:

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
<اقتباس فقرة>   

setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE)؛

وليس فقط يغلق JFrame لكن إغلاق التطبيق بالكامل، وبالتالي "EXIT ON CLOSE"

لتحقيق نفس النتيجة لديك للخروج بشكل فعال التطبيق، لذلك ندعو ببساطة

 System.exit(0);

والتأثير هو نفسه تماما.

وأفضل طريقة لإغلاق إطار سوينغ برمجيا لجعلها تتصرف مثل انها عندما يتم الضغط على زر "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".

إذا كنت حقا لا تريد تطبيق لإنهاء عند إغلاق JFrame ثم،

والاستخدام: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

وبدلا من: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

وإليك ملخص ما يبدو الحل مثل،

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

وهذه أمثلة توضح كيفية تحقيق نافذة عملية إغلاق المؤكدة.

ونافذة لديه محول النافذة التي تبديل عملية إغلاق الافتراضي لEXIT_ON_CLOSEor DO_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));
    }
}

واستنادا إلى الإجابات المقدمة بالفعل هنا، وهذا هو الطريق I تنفيذه:

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

// frame stuffs here ...

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

ووJFrame يحصل على الحدث لإغلاق وعند الختام، مخارج.

وأعطيت هذه الإجابة من طرف أليكس وأود أن أوصي به. لأنها عملت لي وشيء آخر انها واضحة وبسيطة جدا.

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

لديك لادخال المكالمة إلى قائمة انتظار رسالة AWT حتى يتسنى لجميع توقيت يحدث بشكل صحيح، وإلا فإنه لن ترسل تسلسل الحدث الصحيح، وخاصة في برنامج متعدد الخيوط. عندما يتم ذلك يمكنك التعامل مع تسلسل الأحداث الناتجة بالضبط كما تفعل إذا قام المستخدم بالضغط على زر لOS suppled زينت JFrame [س].

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

لقد حاولت كتابة الكود الخاص 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);
    }
}    

هذا يسأل المستخدم إذا كان يريد الخروج من الإطار أو التطبيق.

وإرسال ما كان في هيئة سؤال عن 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();

إذا كنت لا تريد تطبيق لإنهاء عند إغلاق JFrame، استعمال:     setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

و

وبدلا من:     setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE)؛

ومن الوثائق:

وDO_NOTHING_ON_CLOSE (defined in WindowConstants): لا تفعل أي شيء. تتطلب برنامج للتعامل مع العملية في طريقة windowClosing لكائن WindowListener مسجل.

وHIDE_ON_CLOSE (defined in WindowConstants): إخفاء تلقائيا إطار بعد استدعاء أي أجسام WindowListener مسجل

وDISPOSE_ON_CLOSE (defined in WindowConstants): إخفاء تلقائيا والتصرف في إطار بعد استدعاء أي أجسام WindowListener مسجل

وEXIT_ON_CLOSE (defined in JFrame): إنهاء التطبيق باستخدام طريقة الخروج النظام. استخدام هذا فقط في التطبيقات.

وربما يكون مفيدا: يمكنك استخدام setVisible(false) على JFrame الخاص بك إذا كنت ترغب في عرض الإطار نفسه مرة أخرى. استدعاء وإلا dispose() لإزالة كافة الموارد شاشة الأم.

تحليل نسخ من بيتر لانج

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

 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top