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
How to override windowsClosing event in JFrame
提问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 x
button 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 JFrame
then better would be override proper e.g DefaultCloseOperations(JFrame.HIDE_ON_CLOSE)
, method JFrame.EXIT_ON_CLOSE
teminating 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 JFrame
or formWindowClosing
<> WindowClosing
, use implemented method from API
1)那么肯定还有另一个问题,您的代码可能调用另一个JFrame
或formWindowClosing
<> WindowClosing
,使用 API 中的实现方法
public void windowClosing(WindowEvent e) {
2) I'b preferred DefaultCloseOperations(JFrame.HIDE_ON_CLOSE)
,
2)我是首选DefaultCloseOperations(JFrame.HIDE_ON_CLOSE)
,
3) use JDialog
instead 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