Java 如何在JFrame中重写windowsClosing事件

Java 如何在JFrame中重写windowsClosing事件,java,swing,jframe,windowlistener,Java,Swing,Jframe,Windowlistener,我正在开发一个JFrame,它有一个按钮来显示另一个JFrame。在第二个JFrame上,我希望覆盖WindowsClosing事件以隐藏此帧,但不关闭所有应用程序。所以我喜欢这样: 关于第二个JFrame addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(

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

关于第二个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();
}
但当我单击窗口上的
x
按钮时,应用程序仍然关闭。为什么?你能帮我吗

我不能用

setDefaultCloseOperation(DISPOSE_ON_CLOSE);
因为我需要再次显示JFrame,在第一个JFrame的操作过程中添加了一些信息。因此,我使用属性
visible false
初始化第二个JFrame。如果使用dispose,则会丢失另一个JFrame在瞬间添加的信息。所以我用

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

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

您可以完全避开侦听器并使用

setDefaultCloseOperation(DISPOSE_ON_CLOSE);
请注意,默认值是HIDE_ON_CLOSE,因此您想要的行为应该是默认行为。可能您注册了另一个退出应用程序的侦听器


请参见不要创建新的
JFrame
,对于新的容器使用
JDialog
,如果要隐藏
JFrame
,最好覆盖适当的操作,例如
DefaultCloseOperations(JFrame.hide\u ON\u CLOSE)
,方法
JFrame.EXIT_ON_CLOSE
将当前JVM实例simlair指定为
System.EXIT(int)

编辑

1) 然后肯定还有另一个问题,您的代码可能会调用另一个
JFrame
formWindowClosing
WindowClosing
,使用API中的实现方法

public void windowClosing(WindowEvent e) {
2) I'b首选
DefaultCloseOperations(JFrame.HIDE\u ON\u CLOSE)

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

在没有看到更多的设置代码的情况下,很难准确指出您正在经历所述行为的原因,但是这可能是由于defaultCloseOperation设置为在关闭时退出


这里有一个指向演示的链接,显示了您正在寻找的属性,尽管结构有点不同。看看:

添加一个没有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);      
    }
}
这就是您想要的,请尝试以下代码:

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

默认的关闭操作与侦听器的操作完全相同:它隐藏帧。我不明白你为什么不能在以后再使用这个框架。@JBNizet:希望我能对这个答案投上两次或更多的票,这似乎是你想解释的,OP不明白,但我刚刚意识到,这正是你告诉他的。不需要
WindowListener
部分。我从来没有读过关于
Jframe
的默认行为,但是你提到的那个文档启发了我:-)对不起。。我想我没有很好地解释我的问题。。。我不想创建一个用户可以关闭或不关闭窗口的对话框。但我只想把它藏起来。就像我在其中设置的按钮一样。setVisible(false)@JackTurky我认为JDialog很重要:-)JFrames可以作为父对象,不能移动到前/后(因为在API中实现,simple不起作用),您对图标化有问题……不。。只需在窗口关闭时设置为不可见,并通过主jframe中的按钮将其设置为可见即可。@JackTurky hmmmmmm现在???:-),确保
this.setVisible(false)
可以是屏幕上可以聚焦的任何内容:-)对于给定的问题编辑,这个答案是不正确的。呵呵,太对了,希望我能像你一样编写代码。希望那一天快到了:-)@JackTurky:欢迎你并保持微笑:-)@mKorbel:wowowo,我不知道那些数据,很多知识渊博的人都和你一样:-)
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);      
    }
}