有很多刚开始学Swing的人经常问JFrame关闭的时候先询问下是否关闭,即弹出一个对话框让用户点击选择YES或NO,其实稍微进去查看源代码就能找到答案。我们找到那里是发出关闭事件的地方,我们在那个地方进行拦截就可以了,查看源代码可以知道在JFrame中有这么一个方法:
protected void processWindowEvent(WindowEvent e) {
//do Samething。。。。。。。。。。。。。
}
这个方法一直追上去可以发现它是由Window类中派生出来的,我们先看一张图:
从图上看以看出我们常用的JFrame和JDialog都上由Window派生出来的,那么所有基于Window下的窗口点击关闭按钮都是在上述的那个方法中进行判断,那么我们重写那个方法,在里面进行拦截如:
/** *//***
* 重写此方法让用户确认是否需要关闭
* */
@Override
protected void processWindowEvent(WindowEvent e) {
boolean flag = false;
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
//关闭的提示选择
int result= JOptionPane.showConfirmDialog(
this,
("确认要关闭吗?"),
("关闭"),
JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.NO_OPTION){
//不关闭,系统托盘????
flag = true;
}else{
//关闭的处理
}
}
if(!flag){
//点击的了YES,那么交给上面去处理关闭的处理
super.processWindowEvent(e);
}
}
对于JInternalFrame,它是一个轻量级组件,所以它的确认关闭需要做其他处理,查找API就会很发现有这么个方法:doDefaultCloseAction
是处理关闭事件的处理,如果您不放心确实是这个方法,那么你就去找那个关闭按钮发事件的地方才放心的话,那么我们也很容易找到在
JInternalFrame的Title是由BasicInternalFrameTitlePane这个类中负责绘制的,这里就有点击关闭调用doDefaultCloseAction方法的,既然如此那么重写这方法就OK了,代码如下:
/** *//***
* 重写此方法让用户确认是否需要关闭
* */
@Override
public void doDefaultCloseAction(){
//关闭的提示选择
int result= JOptionPane.showConfirmDialog(
this,
("确认要关闭JInternalFrame吗?"),
("关闭"),
JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.YES_OPTION){
//如果选择YES,交由上层设置的关闭处理
super.doDefaultCloseAction();
}
}
总的测试代码如下:
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
/** *//***
* JFrame和JInternalFrame关闭前先确认是否关闭
* @author kissjava
* www.blogjava.net/kissjava
* **/
public class CloseFrameDemo extends JFrame{
public CloseFrameDemo(){
this.setTitle("CloseFrameDemo");
jbInit();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800, 800);
this.setVisible(true);
}
private void jbInit(){
JDesktopPane desktop = new JDesktopPane();
JInternalFrame internalFrame = this.createJInternalFrame();
JButton btn = new JButton("DEMO");
internalFrame.add(btn, "Center");
desktop.add(internalFrame, JDesktopPane.PALETTE_LAYER);
internalFrame.setSize(400,400);
internalFrame.setVisible(true);
this.add(desktop, "Center");
}
private JInternalFrame createJInternalFrame(){
JInternalFrame internalFrame = new JInternalFrame("JInternalFrame Close Demo", true, true, true, true){
/** *//***
* 重写此方法让用户确认是否需要关闭
* */
@Override
public void doDefaultCloseAction(){
//关闭的提示选择
int result= JOptionPane.showConfirmDialog(
this,
("确认要关闭JInternalFrame吗?"),
("关闭"),
JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.YES_OPTION){
//如果选择YES,交由上层设置的关闭处理
super.doDefaultCloseAction();
}
}
};
return internalFrame;
}
/** *//***
* 重写此方法让用户确认是否需要关闭
* */
@Override
protected void processWindowEvent(WindowEvent e) {
boolean flag = false;
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
//关闭的提示选择
int result= JOptionPane.showConfirmDialog(
this,
("确认要关闭吗?"),
("关闭"),
JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.NO_OPTION){
//不关闭,系统托盘????
flag = true;
}else{
//关闭的处理
}
}
if(!flag){
//点击的了YES,那么交给上面去处理关闭的处理
super.processWindowEvent(e);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new CloseFrameDemo();
}
}) ;
}
}