Java 如何在JFrame中重写windowsClosing事件
我正在开发一个JFrame,它有一个按钮来显示另一个JFrame。在第二个JFrame上,我希望覆盖WindowsClosing事件以隐藏此帧,但不关闭所有应用程序。所以我喜欢这样: 关于第二个JFrameJava 如何在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(
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);
}
}