我正在开发Java Swing应用程序。
当我退出应用程序时,会弹出optionDialog,它会询问我是否要在退出之前保存文件。
我想要做的是optionDialog上有三个按钮(YES,NO,CANCEL)我想让optionDialog通过箭头键而不是tab键来改变按钮的焦点。如何在optionDialog中为按钮创建关键监听器?
到目前为止,这是我的代码
Object[] options = {" YES "," NO ","CANCEL"};
int n = JOptionPane.showOptionDialog(Swing4.this,
"File haven't save yet." +
" \n Are you want to save the file?",
"Confirm Dialog",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, //do not use a custom Icon
options, //the titles of buttons
options[1]); //default button title
if(n == JOptionPane.YES_OPTION){
if(helper.updateFile("text.txt", gatherAllContent(), Swing4.this)){
System.exit(0);
}
label.setText("There is something wrong on quit");
}else if(n == JOptionPane.NO_OPTION){
System.exit(0);
}else if(n == JOptionPane.CANCEL_OPTION){
System.out.println("Cancel");
}
使用showOptionDialog
无法做到这一点,相反,你需要为自己创建一个JOptionPane
。你在寻找的是Container.getFocusTraversalKeys()。这是一个使用右键更改按钮焦点的工作片段(Tab仍然有效):
JOptionPane optionPane = new JOptionPane("File haven't save yet." +
" \n Are you want to save the file?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION);
JDialog dialog = optionPane.createDialog("Confirm Dialog");
Set<AWTKeyStroke> focusTraversalKeys = new HashSet<AWTKeyStroke>(dialog.getFocusTraversalKeys(0));
focusTraversalKeys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.VK_UNDEFINED));
dialog.setFocusTraversalKeys(0, focusTraversalKeys);
dialog.setVisible(true);
dialog.dispose();
int option = (Integer) optionPane.getValue();
当我退出应用程序时,会弹出optionDialog,它会询问我是否要在退出之前保存文件。
JFrame
与setDefaultCloseOperation(EXIT_ON_CLOSE);
WindowListener
to JFrame
public void windowClosing()
,然后每个事件firing JOptionPane
with required choices例如
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClosingFrame extends JFrame {
private JMenuBar MenuBar = new JMenuBar();
private JFrame frame = new JFrame();
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) {
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);
}
}
};
frame.addWindowListener(exitListener);
frame.setDefaultCloseOperation(EXIT_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();
}
});
}
}
改进Nandor接受的答案......这将允许您使用向左箭头向后遍历,并在使用X关闭对话框时避免NullPointerException。
public int showConfirmDialog(Component parent, String message, String title)
{
JOptionPane optionPane = new JOptionPane(message, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION);
JDialog dialog = optionPane.createDialog(parent, title);
Set forwardTraversalKeys = new HashSet(dialog.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
forwardTraversalKeys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.VK_UNDEFINED));
dialog.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
Set backwardTraversalKeys = new HashSet(dialog.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
backwardTraversalKeys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_LEFT, KeyEvent.VK_UNDEFINED));
dialog.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardTraversalKeys);
dialog.setVisible(true);
dialog.dispose();
Integer ret = (Integer) optionPane.getValue();
if (ret == null)
{
return JOptionPane.CANCEL_OPTION;
}
return ret.intValue();
}
您可以递归添加KeyListener。这是我按“Enter press”确认对话框的示例。
public static void setEnterKey(Object o, JButton okButton) {
if (okButton == null) {
okButton = getOkButton(o);
}
if (okButton != null) {
if (o instanceof JRootPane) {
JRootPane root = (JRootPane) o;
for (int i = 0; i < root.getComponentCount(); i++) {
Component c = root.getComponent(i);
setEnterKey(c, okButton);
}
} else if (o instanceof JPanel) {
JPanel p = (JPanel) o;
for (int i = 0; i < p.getComponentCount(); i++) {
Component c = p.getComponent(i);
setEnterKey(c, okButton);
}
} else if (o instanceof JLayeredPane) {
JLayeredPane p = (JLayeredPane) o;
for (int i = 0; i < p.getComponentCount(); i++) {
Component c = p.getComponent(i);
setEnterKey(c, okButton);
}
} else if (o instanceof JTabbedPane) {
JTabbedPane p = (JTabbedPane) o;
for (int i = 0; i < p.getComponentCount(); i++) {
Component c = p.getComponent(i);
setEnterKey(c, okButton);
}
} else if (o instanceof JOptionPane) {
JOptionPane p = (JOptionPane) o;
for (int i = 0; i < p.getComponentCount(); i++) {
Component c = p.getComponent(i);
setEnterKey(c, okButton);
}
} else if (o instanceof Component) {
if (!(o instanceof JTextArea) && !(o instanceof JTable) && !(o instanceof JTextPane)) {
final JButton bt = okButton;
((Component) o).addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
bt.doClick();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
}
}
}
}
public static JButton getOkButton(Object o) {
JButton button = null;
if (o instanceof JRootPane) {
JRootPane root = (JRootPane) o;
for (int i = 0; i < root.getComponentCount() && button == null; i++) {
Component c = root.getComponent(i);
button = getOkButton(c);
}
} else if (o instanceof JPanel) {
JPanel p = (JPanel) o;
for (int i = 0; i < p.getComponentCount() && button == null; i++) {
Component c = p.getComponent(i);
button = getOkButton(c);
}
} else if (o instanceof JLayeredPane) {
JLayeredPane p = (JLayeredPane) o;
for (int i = 0; i < p.getComponentCount() && button == null; i++) {
Component c = p.getComponent(i);
button = getOkButton(c);
}
} else if (o instanceof JTabbedPane) {
JTabbedPane p = (JTabbedPane) o;
for (int i = 0; i < p.getComponentCount() && button == null; i++) {
Component c = p.getComponent(i);
button = getOkButton(c);
}
} else if (o instanceof JOptionPane) {
JOptionPane p = (JOptionPane) o;
for (int i = 0; i < p.getComponentCount() && button == null; i++) {
Component c = p.getComponent(i);
button = getOkButton(c);
}
} else if (o instanceof JButton) {
JButton b = (JButton) o;
if (b.getText().equalsIgnoreCase("ok")) {
button = b;
}
}
return button;
}