Java 如何覆盖JFrame close('x')按钮的默认侦听器?
我想要3种退出应用程序的方法 按CTRL-Q键 从菜单栏中选择“退出” 关闭JFrame上的“x”按钮 到目前为止,我所做的是为前两个添加偶数侦听器,但我不知道如何让JFrame close'x'按钮执行相同的操作。目前,它只是在不提示确认的情况下退出应用程序,因为它不知道如何进行确认。我基本上希望在用户确认他们想要退出后,所有的帧都被处理掉。在前两种情况下会发生这种情况,原因很简单,因为它们的操作侦听器调用一个确认退出的退出方法,然后继续处理所有帧Java 如何覆盖JFrame close('x')按钮的默认侦听器?,java,swing,exit,windowlistener,Java,Swing,Exit,Windowlistener,我想要3种退出应用程序的方法 按CTRL-Q键 从菜单栏中选择“退出” 关闭JFrame上的“x”按钮 到目前为止,我所做的是为前两个添加偶数侦听器,但我不知道如何让JFrame close'x'按钮执行相同的操作。目前,它只是在不提示确认的情况下退出应用程序,因为它不知道如何进行确认。我基本上希望在用户确认他们想要退出后,所有的帧都被处理掉。在前两种情况下会发生这种情况,原因很简单,因为它们的操作侦听器调用一个确认退出的退出方法,然后继续处理所有帧 public class MainWindo
public class MainWindow extends JFrame {
...
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowListener() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
...
// this is part of the main menu bar (case #2)
JMenuItem mntmExit = new JMenuItem("Exit");
mntmExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainWindow.this.exit();
}
});
// this is case #1
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_Q && e.getModifiers() == InputEvent.CTRL_MASK) {
MainWindow.this.exit();
}
return false;
}
});
}
// the exit method
private void exit() {
int confirmed = JOptionPane.showConfirmDialog(this, "Are you sure you want to quit?", "Confirm quit", JOptionPane.YES_NO_OPTION);
if(confirmed == JOptionPane.YES_OPTION) {
Frame[] frames = Frame.getFrames();
for(Frame frame : frames) {
frame.dispose();
}
}
}
是否可以为“关闭”按钮分配一个操作侦听器?如果没有,是否有其他方法可以解决此问题?在windowClosing方法中,在System.exit之前调用exit方法
这将在单击X时自动关闭java程序。在windowClosing方法中,在System.exit之前调用exit方法
这将在您单击X时自动关闭java程序。将JFrame的默认关闭操作保留为JFrame。在关闭时不执行任何操作,但使用WindowListener或更简洁的WindowAdapter来侦听关闭尝试 您可以对菜单项和按钮使用相同的抽象操作,然后在WindowListener中调用该操作的方法。比如说
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class ClosingJFrame {
public static void main(String[] args) {
final JFrame frame = new JFrame("My Frame");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
final CloseAction closeAction = new CloseAction(frame);
JPanel panel = new JPanel();
panel.add(new JButton(closeAction));
JMenuItem exitMenuItem = new JMenuItem(closeAction);
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
menu.add(exitMenuItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
closeAction.confirmClosing();
}
});
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class CloseAction extends AbstractAction {
private JFrame mainFrame;
public CloseAction(JFrame mainFrame) {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
this.mainFrame = mainFrame;
}
@Override
public void actionPerformed(ActionEvent e) {
confirmClosing();
}
public void confirmClosing() {
int confirmed = JOptionPane.showConfirmDialog(mainFrame,
"Are you sure you want to quit?", "Confirm quit",
JOptionPane.YES_NO_OPTION);
if (confirmed == JOptionPane.YES_OPTION) {
// clean up code
System.exit(0);
}
}
}
编辑
哎呀,我忘了按ctrl-Q键了。对此使用相同的操作,并使用键绑定将其绑定到ctrl-q键。改进后的代码:
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class ClosingJFrame {
public static void main(String[] args) {
final JFrame frame = new JFrame("My Frame");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
final CloseAction closeAction = new CloseAction(frame);
JPanel panel = new JPanel();
panel.add(new JButton(closeAction));
JMenuItem exitMenuItem = new JMenuItem(closeAction);
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
menu.add(exitMenuItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
closeAction.confirmClosing();
}
});
// also use the same Action in your ctrl-q key bindings
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = panel.getInputMap(condition);
ActionMap actionMap = panel.getActionMap();
KeyStroke ctrlQKey = KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK);
inputMap.put(ctrlQKey, ctrlQKey.toString());
actionMap.put(ctrlQKey.toString(), closeAction);
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class CloseAction extends AbstractAction {
private JFrame mainFrame;
public CloseAction(JFrame mainFrame) {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
this.mainFrame = mainFrame;
}
@Override
public void actionPerformed(ActionEvent e) {
confirmClosing();
}
public void confirmClosing() {
int confirmed = JOptionPane.showConfirmDialog(mainFrame,
"Are you sure you want to quit?", "Confirm quit",
JOptionPane.YES_NO_OPTION);
if (confirmed == JOptionPane.YES_OPTION) {
// clean up code
System.exit(0);
}
}
}
编辑2
这一声明使我感到关切:
然后继续处理所有帧
这意味着您有多个jframe。如果是这样,您应该阅读此链接,因为它将解释为什么通常不希望这样做:
编辑3
根据Rob Camick的评论:
您还可以通过执行以下操作为CloseAction设置加速器:
然后菜单项将为您进行键绑定
这将进入CloseAction的构造函数,如下所示:
public CloseAction(JFrame mainFrame) {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("control Q"));
this.mainFrame = mainFrame;
}
将JFrame的默认关闭操作保留为JFrame.DO_NOTHING_ON_close,但使用WindowListener或更简洁的WindowAdapter侦听关闭尝试 您可以对菜单项和按钮使用相同的抽象操作,然后在WindowListener中调用该操作的方法。比如说
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class ClosingJFrame {
public static void main(String[] args) {
final JFrame frame = new JFrame("My Frame");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
final CloseAction closeAction = new CloseAction(frame);
JPanel panel = new JPanel();
panel.add(new JButton(closeAction));
JMenuItem exitMenuItem = new JMenuItem(closeAction);
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
menu.add(exitMenuItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
closeAction.confirmClosing();
}
});
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class CloseAction extends AbstractAction {
private JFrame mainFrame;
public CloseAction(JFrame mainFrame) {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
this.mainFrame = mainFrame;
}
@Override
public void actionPerformed(ActionEvent e) {
confirmClosing();
}
public void confirmClosing() {
int confirmed = JOptionPane.showConfirmDialog(mainFrame,
"Are you sure you want to quit?", "Confirm quit",
JOptionPane.YES_NO_OPTION);
if (confirmed == JOptionPane.YES_OPTION) {
// clean up code
System.exit(0);
}
}
}
编辑
哎呀,我忘了按ctrl-Q键了。对此使用相同的操作,并使用键绑定将其绑定到ctrl-q键。改进后的代码:
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class ClosingJFrame {
public static void main(String[] args) {
final JFrame frame = new JFrame("My Frame");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
final CloseAction closeAction = new CloseAction(frame);
JPanel panel = new JPanel();
panel.add(new JButton(closeAction));
JMenuItem exitMenuItem = new JMenuItem(closeAction);
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
menu.add(exitMenuItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
frame.setJMenuBar(menuBar);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
closeAction.confirmClosing();
}
});
// also use the same Action in your ctrl-q key bindings
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = panel.getInputMap(condition);
ActionMap actionMap = panel.getActionMap();
KeyStroke ctrlQKey = KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK);
inputMap.put(ctrlQKey, ctrlQKey.toString());
actionMap.put(ctrlQKey.toString(), closeAction);
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class CloseAction extends AbstractAction {
private JFrame mainFrame;
public CloseAction(JFrame mainFrame) {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
this.mainFrame = mainFrame;
}
@Override
public void actionPerformed(ActionEvent e) {
confirmClosing();
}
public void confirmClosing() {
int confirmed = JOptionPane.showConfirmDialog(mainFrame,
"Are you sure you want to quit?", "Confirm quit",
JOptionPane.YES_NO_OPTION);
if (confirmed == JOptionPane.YES_OPTION) {
// clean up code
System.exit(0);
}
}
}
编辑2
这一声明使我感到关切:
然后继续处理所有帧
这意味着您有多个jframe。如果是这样,您应该阅读此链接,因为它将解释为什么通常不希望这样做:
编辑3
根据Rob Camick的评论:
您还可以通过执行以下操作为CloseAction设置加速器:
然后菜单项将为您进行键绑定
这将进入CloseAction的构造函数,如下所示:
public CloseAction(JFrame mainFrame) {
super("Exit");
putValue(MNEMONIC_KEY, KeyEvent.VK_X);
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("control Q"));
this.mainFrame = mainFrame;
}
+1.您也可以通过如下操作为CloseAction设置加速器:putValueACCELERATOR\u KEY,KeyStroke.getKeyStrokecontrol Q;。然后菜单项将为您进行键绑定。+1。您还可以通过执行以下操作为CloseAction设置加速器:putValueACCELERATOR\u KEY,KeyStroke.getKeyStrokecontrol Q;。然后,该菜单项将为您执行键绑定。请参阅,以获得一个简单的接口,该接口可以使您只需编写自定义操作即可更轻松地实现这些要求。请参阅,以获得一个简单的接口,该接口可以使您只需编写自定义操作即可更轻松地实现这些要求。