Java JOptionPane.YES\u选项==在每个按钮上输入

Java JOptionPane.YES\u选项==在每个按钮上输入,java,swing,joptionpane,Java,Swing,Joptionpane,我有这样一个选项对话框: String[] options = ["Yes", "No"]; //button names int n = JOptionPane.showOptionDialog(singleFrameService.getFrame(), "Some Question?", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,

我有这样一个选项对话框:

String[]  options = ["Yes", "No"]; //button names

int n = JOptionPane.showOptionDialog(singleFrameService.getFrame(),
        "Some Question?",
        "",
        JOptionPane.YES_NO_OPTION,
        JOptionPane.QUESTION_MESSAGE,
        null,     //do not use a custom Icon
        options,  //the titles of buttons
        options[0]); //default button title

//if press yes
if (n == JOptionPane.YES_OPTION){
    //make some if pressed Yes
}
当我使用鼠标并按下是/否-所有工作正常。。。
但是,当我开始使用键盘时,按TAB键转到“否”按钮,然后按ENTER-work“Yes”选项,这一切都取决于外观和感觉,好的。在您的L&F中,“回车”表示“按默认按钮”(是)。按下聚焦按钮可能是通过按下空格键来完成的。

除了JB Nizet的回答之外,如果我理解得很好,我还想提到java中的输入处理是这样的:

  • 聚焦窗口中的组件
  • 具有焦点的组件
  • 作为聚焦容器祖先的组件
  • 所有这些都是按照与添加顺序相反的顺序进行的(我不是100%这么认为,但这是合乎逻辑的)。现在,可以使用inputEvent。在这种情况下,按下enter键的JOptionPane寄存器将遍历具有绑定到输入事件的操作的组件集合。
    yes
    按钮作为默认按钮使用该事件,因此其他组件无法对其执行任何操作


    问题的解决方案是必须创建一个自定义JDialog。给它一个消息标签,一个图标占位符和两个按钮。现在,制作与您使用的JOptionPane相同的构造函数,并根据构造函数接收的参数为每个组件提供文本/图标。

    除了JB Nizet的答案之外,我想建议,如果您不能使用
    ENTER
    键访问
    是,否
    按钮,请尝试禁用该键。这里有一些例子:

    public class NewClass {
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        String[] options = {"Yes", "No"};
    
        int n = JOptionPane.showOptionDialog(frame,
                "Some Question? Press space bar to continue...",
                "",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null, //do not use a custom Icon
                options, //the titles of buttons
                null); // disabled the ENTER Key
    
        System.out.println(n);
    
        if (n == JOptionPane.YES_OPTION) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    
    
        System.exit(1);
    }
    }
    

    我需要JOptionPane以与响应空格键相同的方式响应返回键,这就是我成功完成此操作的原因: 我创建了JOPtionPane的一个新实例,并调用了它的createDialog方法来获取它的对话框窗口

    然后我将它的对话框窗口传递给下面的listComponents(java.awt.Container)方法,这就成功了

        private static index=0;
    private static void listComponents(java.awt.Container c){
            if(c==null)return;
            for(java.awt.Component cc:c.getComponents())
                listComponents((java.awt.Container)cc);
            if(c instanceof javax.swing.JButton){
                buttons[index++]=(javax.swing.JButton)c;
                javax.swing.InputMap inputMap=buttons[index-1].getInputMap(javax.swing.JComponent.WHEN_FOCUSED);
                javax.swing.Action spaceAction=buttons[index-1].getActionMap().get(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SPACE,0));
                inputMap.put(javax.swing.KeyStroke
    .getKeyStroke(java.awt.event.KeyEvent.VK_ENTER,0),spaceAction);
            }
        }
    

    这将使uimanager处理聚焦按钮。这将允许您使用enter或space来选择聚焦按钮

    UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
    

    “工作是选择”是什么意思?您希望它执行“是”选项还是“否”选项;在我的代码中,no work no==JOptionPane.YES\u选项作为“YES”@MarioDeSchaepmeester:Oleg Beat意味着当他试图使用
    no
    选项顶部的
    ENTER\u键时,它仍然会处理条件
    if(n==JOptionPane.YES\u选项){//如果按了YES就做一些}
    @Crazenezz这样做吗?这很奇怪,因为当我的焦点在文本字段中时,我无法在自定义JDialog上用enter键触发默认按钮。。。这可能是因为这些文本字段有聚焦策略,但仍然。。。我认为处理按键事件的顺序首先是有焦点的按钮?@MarioDeSchaepmeester:我尝试过,发现当使用
    ENTER
    键时,返回值始终为0,但当使用
    SPACE\u BAR
    键时,返回值将与使用鼠标单击时相同。焦点在“否”上,然后按ENTER键。我明白这一点。我说的是“回车”的意思是“按默认按钮”。这与“按下聚焦按钮”不同。要按下聚焦按钮,请使用空格键。如果有一种简单的方法让“Y”和“N”表示是和否,我的背部会有一些压力。使用空格键表示默认选项会有很大的阻力。我知道这是标准的,但大多数人从来没有这样做过——他们使用鼠标。一、 然而,将一个有着20年历史的DOS应用程序移植到一个更现代的平台上,这是一项令人不快的任务,人们希望它能像旧的一样工作——而且他们不想把手从键盘上拿下来。上帝保佑我!虽然代码与您描述的一样,但作为一个用户,我不会对这种行为感到非常满意。我不知道使用了哪个操作系统,以及哪个外观和感觉,但遇到的行为可能与默认操作系统行为完全匹配。作为一个用户,我更希望我的Java应用程序能以同样的方式工作,而不是忽略我的输入key@Robin:我同意你作为用户的说法,如果我有更多可定制的东西,我会更新我的答案。