Java 如何覆盖 JFrame 中的 windowsClosing 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9725311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:46:32  来源:igfitidea点击:

How to override windowsClosing event in JFrame

javaswingjframewindowlistener

提问by HymanTurky

i'm developing a JFrame which has a button to show another JFrame. On the second JFrame i want to override WindowsClosing event to hide this frame but not close all the application. So i do like this:

我正在开发一个 JFrame,它有一个按钮来显示另一个 JFrame。在第二个 JFrame 上,我想覆盖 WindowsClosing 事件以隐藏此框架但不关闭所有应用程序。所以我喜欢这样:

On second JFrame

在第二个 JFrame 上

addWindowListener(new java.awt.event.WindowAdapter() {
    public void windowClosing(java.awt.event.WindowEvent evt) {
         formWindowClosing(evt);
    }
});

private void formWindowClosing(java.awt.event.WindowEvent evt) {
    this.dispose();
}

but application still close when i click xbutton on the windows. why? can you help me?

但是当我单击x窗口上的按钮时,应用程序仍然关闭。为什么?你能帮助我吗?

I can't use

我不能用

setDefaultCloseOperation(DISPOSE_ON_CLOSE);

because i need to show again that JFrame with some information added in it during operations from first JFrame. So i init second JFrame with attribute visible false. if i use dispose i lose the information added in a second moment by the other JFrame. so i use

因为我需要再次显示 JFrame,并在从第一个 JFrame 操作期间添加了一些信息。所以我用属性初始化第二个 JFrame visible false。如果我使用 dispose 我会丢失另一个 JFrame 在第二个时刻添加的信息。所以我用

private void formWindowClosing(java.awt.event.WindowEvent evt) {
    this.setVisible(false);
}

but it still continue to terminate my entire app.

但它仍然继续终止我的整个应用程序。

采纳答案by nIcE cOw

Adding a New Code with no WindowListener part as explained by @JBNizet, the very right thing. The default behaviour just hides the window, nothing is lost, you simply have to bring it back, every value inside it will remain as is, below is the sample program for further help :

添加一个没有 WindowListener 部分的新代码,正如@JBNizet 所解释的那样,非常正确。默认行为只是隐藏窗口,不会丢失任何内容,您只需将其带回来,其中的每个值都将保持原样,下面是示例程序以获取进一步帮助:

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

public class TwoFrames
{
    private SecondFrame secondFrame;
    private int count = 0;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("JFRAME 1");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        secondFrame = new SecondFrame();
        secondFrame.createAndDisplayGUI();
        secondFrame.tfield.setText("I will be same everytime.");

        JPanel contentPane = new JPanel();  
        JButton showButton = new JButton("SHOW JFRAME 2");
        showButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                secondFrame.tfield.setText(secondFrame.tfield.getText() + count);
                count++;
                if (!(secondFrame.isShowing()))
                    secondFrame.setVisible(true);
            }
        });

        frame.add(contentPane, BorderLayout.CENTER);
        frame.add(showButton, BorderLayout.PAGE_END);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TwoFrames().createAndDisplayGUI();
            }
        });
    }
}

class SecondFrame extends JFrame
{
    private WindowAdapter windowAdapter;
    public JTextField tfield;

    public void createAndDisplayGUI()
    {
        setLocationByPlatform(true);

        JPanel contentPane = new JPanel();

         tfield = new JTextField(10);

        addWindowListener(windowAdapter);
        contentPane.add(tfield);

        getContentPane().add(contentPane);
        setSize(300, 300);      
    }
}

Is this what you want, try this code :

这是你想要的吗,试试这个代码:

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

public class TwoFrames
{
    private SecondFrame secondFrame;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("JFRAME 1");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);

        secondFrame = new SecondFrame();
        secondFrame.createAndDisplayGUI();
        secondFrame.tfield.setText("I will be same everytime.");

        JPanel contentPane = new JPanel();  
        JButton showButton = new JButton("SHOW JFRAME 2");
        showButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (!(secondFrame.isShowing()))
                    secondFrame.setVisible(true);
            }
        });

        frame.add(contentPane, BorderLayout.CENTER);
        frame.add(showButton, BorderLayout.PAGE_END);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TwoFrames().createAndDisplayGUI();
            }
        });
    }
}

class SecondFrame extends JFrame
{
    private WindowAdapter windowAdapter;
    public JTextField tfield;

    public void createAndDisplayGUI()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);

        JPanel contentPane = new JPanel();

         tfield = new JTextField(10);

        windowAdapter = new WindowAdapter()
        {
            public void windowClosing(WindowEvent we)
            {
                setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
            }
        };

        addWindowListener(windowAdapter);
        contentPane.add(tfield);

        getContentPane().add(contentPane);
        setSize(300, 300);      
    }
}

回答by JB Nizet

You could avoid the listener completely and use

您可以完全避免监听器并使用

setDefaultCloseOperation(DISPOSE_ON_CLOSE);

Note that the default value is HIDE_ON_CLOSE, so the behavior you want should be the default behavior. Maybe you registered another listener that exits the application.

请注意,默认值为 HIDE_ON_CLOSE,因此您想要的行为应该是默认行为。也许您注册了另一个退出应用程序的侦听器。

See http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29

请参阅http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29

回答by mKorbel

don't create a new JFrame, for new container use JDialog, if you want to hide the JFramethen better would be override proper e.g DefaultCloseOperations(JFrame.HIDE_ON_CLOSE), method JFrame.EXIT_ON_CLOSEteminating current JVM instance simlair as calll for System.exit(int)

不要JFrame为新的容器使用创建一个新的,JDialog如果你想隐藏JFrame那么更好的方法是覆盖正确的,例如DefaultCloseOperations(JFrame.HIDE_ON_CLOSE),方法JFrame.EXIT_ON_CLOSE终止当前的 JVM 实例 simlair 作为 calll forSystem.exit(int)

EDIT

编辑

but it still continue to terminate my entire app. 

1) then there must be another issue, your code maybe call another JFrameor formWindowClosing<> WindowClosing, use implemented method from API

1)那么肯定还有另一个问题,您的代码可能调用另一个JFrameformWindowClosing<> WindowClosing,使用 API 中的实现方法

public void windowClosing(WindowEvent e) {

2) I'b preferred DefaultCloseOperations(JFrame.HIDE_ON_CLOSE),

2)我是首选DefaultCloseOperations(JFrame.HIDE_ON_CLOSE)

3) use JDialoginstead of JFrame

3) 使用JDialog代替JFrame

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

public class ClosingFrame extends JFrame {

    private JMenuBar MenuBar = new JMenuBar();
    private static JFrame frame = new JFrame();
    private static JFrame frame1 = new JFrame("DefaultCloseOperation(JFrame.HIDE_ON_CLOSE)");
    private static final long serialVersionUID = 1L;
    private JMenu File = new JMenu("File");
    private JMenuItem Exit = new JMenuItem("Exit");

    public ClosingFrame() {
        File.add(Exit);
        MenuBar.add(File);
        Exit.addActionListener(new ExitListener());
        WindowListener exitListener = new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                frame.setVisible(false);
                /*int confirm = JOptionPane.showOptionDialog(frame,
                "Are You Sure to Close this Application?",
                "Exit Confirmation", JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE, null, null, null);
                if (confirm == JOptionPane.YES_OPTION) {
                System.exit(1);
                }*/
            }
        };
        JButton btn = new JButton("Show second JFrame");
        btn.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                frame1.setVisible(true);
            }
        });
        frame.add(btn, BorderLayout.SOUTH);
        frame.addWindowListener(exitListener);
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setJMenuBar(MenuBar);
        frame.setPreferredSize(new Dimension(400, 300));
        frame.setLocation(100, 100);
        frame.pack();
        frame.setVisible(true);
    }

    private class ExitListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            int confirm = JOptionPane.showOptionDialog(frame,
                    "Are You Sure to Close this Application?",
                    "Exit Confirmation", JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE, null, null, null);
            if (confirm == JOptionPane.YES_OPTION) {
                System.exit(1);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ClosingFrame cf = new ClosingFrame();
                JButton btn = new JButton("Show first JFrame");
                btn.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        frame.setVisible(true);
                    }
                });
                frame1.add(btn, BorderLayout.SOUTH);
                frame1.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                frame1.setPreferredSize(new Dimension(400, 300));
                frame1.setLocation(100, 400);
                frame1.pack();
                frame1.setVisible(true);
            }
        });
    }
}

回答by Michael

It's hard to pinpoint exactly why you are experiencing the behavior stated without seeing a little more of the set-up code, however it may be due to defaultCloseOperation set to EXIT_ON_CLOSE.

在没有看到更多设置代码的情况下,很难准确指出您遇到所述行为的确切原因,但这可能是由于 defaultCloseOperation 设置为 EXIT_ON_CLOSE。

Here's a link to a demo displaying the properties you are looking for although the structure is a bit different. Have a look: http://docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameworkProject/src/components/Framework.java

这是一个演示链接,该演示显示您正在查找的属性,尽管结构略有不同。看看:http: //docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameworkProject/src/components/Framework.java