如何在JFrame中覆盖windowsClosing事件

我正在开发一个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的操作过程中添加了一些信息。 所以我初始化第二个JFrame,属性visible false 。 如果我使用dispose,我将失去另一个JFrame在第二时刻添加的信息。 所以我用

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

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

正如@JBNizet所解释的,添加一个没有WindowListener部分的新代码,这是非常正确的事情。 默认行为只是隐藏窗口,没有任何丢失,你只需要将其恢复,其中的每个值都将保持原样,下面是示例程序以获得进一步的帮助:

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

不要为新容器使用JDialog创建新的JFrame ,如果你想隐藏JFrame那么最好覆盖正确的例如DefaultCloseOperations(JFrame.HIDE_ON_CLOSE) ,方法JFrame.EXIT_ON_CLOSE将当前的JVM实例simlair作为System.exit(int) calll进行tellating System.exit(int)

编辑

 but it still continue to terminate my entire app. 

1)然后必须有另一个问题,你的代码可能会调用另一个JFrameformWindowClosing <> WindowClosing ,使用API​​实现的方法

 public void windowClosing(WindowEvent e) { 

2)我更喜欢DefaultCloseOperations(JFrame.HIDE_ON_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); } }); } } 

您可以完全避免使用侦听器

 setDefaultCloseOperation(DISPOSE_ON_CLOSE); 

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

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

如果没有看到更多的设置代码,很难确切地确定您遇到所述行为的原因,但这可能是由于defaultCloseOperation设置为EXIT_ON_CLOSE。

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