如何在JComboBox中检测TAB按键?

Dej*_*kic 3 java swing key-bindings jcombobox

我试图找出如何检测当用户按Tab键或通过鼠标单击组件区域外时JComboBox是否失去焦点.

将FocusListener添加到JComboBox的编辑器组件对我没有帮助,因为我无法确定用户是否使用了鼠标或通过tab键移动了焦点.任何想法将不胜感激.

编辑1:我想要实现的是:

  • 假设用户下拉列表(JComboBox popupMenu显示),并通过光标键导航...
  • 案例1:用户按Tab键.在这种情况下,我想从项目中删除一些信息,只显示一些部分.
  • 案例2:用户在popupMenu区域外点击鼠标(这里我们有子类,但它们都属于同一类别).在这种情况下,我想更改JComboBox以显示以前编辑的项目,而不是用户导航的内容...
  • 还有其他几种情况(鼠标项目选择,回车键,转义等).我可以轻松处理这些,但检测选项卡很棘手,因为我无法捕获此事件,因为它由FocusManager处理.

编辑2:似乎我必须使用setFocusTraversalKeysEnabled(false)在TAB被按下时获得通知,当我捕获该事件时,我应该手动转移焦点...我不喜欢这个解决方案,但这是迄今为止我能来的最好的起来.

解:

以下Java代码实际上解决了我的问题.正如我在Edit 2中所写,最简单的解决方案是禁用焦点遍历.我无耻地借用了Kleopatra的代码,现在一切正常.:)

    if (!isTableCellEditor()) {
        comboBoxEditor.setFocusTraversalKeysEnabled(false);

        Action myAction = new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                handleTabPress();
                comboBoxEditor.transferFocus();
            } // actionPerformed() method
        };

        comboBoxEditor.getActionMap().put("tab-action", myAction);
        comboBoxEditor.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
            .put(KeyStroke.getKeyStroke("TAB"), "tab-action");
    } // if
Run Code Online (Sandbox Code Playgroud)

感谢所有参与者的讨论!

kle*_*tra 6

据我了解你的问题,有两个不同的问题

  • 导航时不提交值
  • 接管对TAB的反应

如果是这样,答案是

  • 配置组合使它认为它是CellEditor的编辑组件
  • 禁用组合的默认遍历键,并使用自定义绑定接管

在代码中:

    final JComboBox simpleBox = new JComboBox(Locale.getAvailableLocales());
    // this line configures the combo to only commit on ENTER 
    // or selecting an item from the list
    simpleBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
    //
    // simpleBox.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
    //     Collections.EMPTY_SET);
    // just noticed the OPs edit - following indeed is easier to disable _all_ traversal
    // keys with one statement
    simpleBox.setFocusTraversalKeysEnabled(false);

    Action myAction = new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            LOG.info("got it!");
            simpleBox.transferFocus();
        }

    };
    simpleBox.getActionMap().put("tab-action", myAction);
    simpleBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
       .put(KeyStroke.getKeyStroke("TAB"), "tab-action");
Run Code Online (Sandbox Code Playgroud)