1

我正在开发 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");
}
4

4 回答 4

6

用 做这个是不可能的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();
于 2013-04-08T10:45:51.620 回答
2

当我退出应用程序时,会弹出 optionDialog 并询问我是否要在退出前保存文件。

例如

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();
            }
        });
    }
}
于 2013-04-08T10:12:55.190 回答
1

改进 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();
}
于 2015-09-17T18:57:45.400 回答
0

您可以递归地添加 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;
}
于 2019-03-01T07:07:22.683 回答