Java JOptionPane-将keylistener添加到showOptionDialog
我正在开发JavaSwing应用程序 当我退出应用程序时,optionDialog会弹出,它会在退出前询问我是否要保存文件 我想做的是Option Dialog上有三个按钮YES,NO,CANCEL我想让Option Dialog通过箭头键而不是tab键改变按钮的焦点。如何在optionDialog中为按钮创建密钥侦听器 到目前为止,这是我的代码Java JOptionPane-将keylistener添加到showOptionDialog,java,swing,joptionpane,Java,Swing,Joptionpane,我正在开发JavaSwing应用程序 当我退出应用程序时,optionDialog会弹出,它会在退出前询问我是否要保存文件 我想做的是Option Dialog上有三个按钮YES,NO,CANCEL我想让Option Dialog通过箭头键而不是tab键改变按钮的焦点。如何在optionDialog中为按钮创建密钥侦听器 到目前为止,这是我的代码 Object[] options = {" YES "," NO ","CANCEL"}; int n = JOptionPane.showOpti
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");
}
当我退出应用程序时,optionDialog将弹出,它将询问
如果我想在退出前保存文件,请告诉我
伪代码,带有setDefaultCloseOperationEXIT_ON_CLOSE
增加
覆盖公共无效窗口关闭,然后每个事件
比如说
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();
}
});
}
}
当我退出应用程序时,optionDialog将弹出,它将询问
如果我想在退出前保存文件,请告诉我
伪代码,带有setDefaultCloseOperationEXIT_ON_CLOSE
增加
覆盖公共无效窗口关闭,然后每个事件
比如说
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();
}
});
}
}
使用showOptionDialog无法做到这一点,相反,您需要为自己创建一个JOptionPane。你要找的是。下面是一个工作片段,可以使用“右键”选项卡更改按钮焦点,但仍然有效:
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();
使用showOptionDialog无法做到这一点,相反,您需要为自己创建一个JOptionPane。你要找的是。下面是一个工作片段,可以使用“右键”选项卡更改按钮焦点,但仍然有效:
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();
改进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();
}
改进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键”确认对话框的示例
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;
}
您可以递归地添加KeyListener。这是我的“按Enter键”确认对话框的示例
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;
}
我非常感谢你的友好和容易理解的回答。但我要问的是如何向JOptionPane.showOptionDialog添加类似keylistener的内容。抱歉,这个问题不是用非常好的英语提问的。在所有情况下,在Swing GUI中使用KeyListener,而不是在几分钟内创建作业创建自己的JDialog setDefaultCloseOperation.HIDE_ON_CLOSE使用三个JButton,将Swing Action、ActionListener添加到每个JButton,创建此JDialof仅一次隐藏此容器与JButtons events一起使用我非常感谢您的友好且易于理解的答案。但我要问的是如何向JOptionPane.showOptionDialog添加类似keylistener的内容。抱歉,这个问题不是用非常好的英语提问的。在所有情况下,在Swing GUI中使用KeyListener,而不是在几分钟内创建作业创建自己的JDialog setDefaultCloseOperation.HIDE_ON_CLOSE使用三个JButton,将Swing Action、ActionListener添加到每个JButton,创建此JDialof仅一次隐藏此容器连同JButtons eventYa!这正是我要找的!这是我的另一个问题。我如何知道我按下了哪个按钮?JOptionPane.showOptionDialog返回按下哪个按钮的结果。在这种情况下,我应该使用什么方法来获取结果a!这正是我要找的!这是我的另一个问题。我如何知道我按下了哪个按钮?JOptionPane.showOptionDialog返回按下哪个按钮的结果。在这种情况下,我应该使用什么方法来获得结果