如何检测JComboBox中的TAB按键?
我想了解如何检测JComboBox是否在用户按下Tab或通过在组件区域外单击鼠标时失去焦点。如何检测JComboBox中的TAB按键?
将FocusListener添加到JComboBox的编辑器组件并不能帮助我,因为我无法确定用户是否使用鼠标或通过Tab键移动焦点。任何想法将不胜感激。
编辑1: 我想实现的是:
- 假设用户下拉列表(JComboBox中弹出菜单显示出来),并通过光标键导航...
- 案例1:用户按下标签。在这种情况下,我想切断项目中的一些信息,只显示一些部分。第二种情况:用户在popupMenu的区域外点击鼠标(这里我们有子库,但它们都属于同一个类别)。在这种情况下,我想要更改JComboBox以显示以前编辑的项目,而不是用户导航的项目...
- 还有其他几种情况(鼠标项拾取,输入键,转义等)。我可以很容易地处理这些,但检测标签是棘手的,因为我无法捕捉这个事件,因为它由FocusManager处理。
编辑2: 看来,我必须使用setFocusTraversalKeysEnabled(false)
按下TAB时得到通知,当我捕捉事件,我应该手动转移焦点......我不喜欢这样的解决方案,但是迄今为止我能想到的最好的。
解决方案:
下面的一段Java代码实际上是解决我的问题。正如我在编辑2最简单的解决方案是禁用焦点遍历。我无耻地借用了克列奥帕特拉的代码,现在所有的作品。 :)
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
感谢所有与会者的讨论!
当我明白你的问题,有两个独立的问题
- 在导航的同时
- 接管反应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");
感谢Kleopatra,终于明白这个问题的人......当我的组合框处于一种形式(而不是单元编辑器)时,我什么都不做。这全是自动的。正如您可能知道的那样,在您导航时,会自动调用setSelectedItem()。所以,我所做的是 - 当用户按下ENTER时,或使用鼠标选择一个项目时,我存储该项目,所以我知道哪些项目实际选中。 (这等于不提交,因为我总是显示最新的PICKED项目)。我不能确定它是一个单元格编辑器,因为当它是一个单元格编辑器时,我有单独的逻辑...... :( – DejanLekic 2012-02-12 15:55:16
如果你看看我的*编辑2 *,你会看到我我想现在就做...这似乎是最简单的解决方案,你在想什么 – DejanLekic 2012-02-12 16:01:02
可能不知道你在做什么之后;-)设置客户端属性会使组合表现得像你描述你的需求,IMO:用户可以浏览没有提交(又名:选择组合)在下拉列表中选择的项目。如果他/她想提交,他/她已经这么做了 - 无论是按ENTER还是通过鼠标点击进入下拉菜单。没有其他代码可用于“点击”情况 – kleopatra 2012-02-12 16:10:01
假设您在松开焦点之前已按下鼠标(或键)。因此,倾听所有的键盘和鼠标点击,并且在丢失焦点之前使用的那个是罪魁祸首。
当focuslost被触发时,您会检查您在窗口的任何部分按下鼠标或键时设置的变量。这个变量只记录最后一个鼠标和/或键被按下。当然,你必须捕获所有的鼠标和按键,因为点击任何小部件会让你失去焦点。
FocusLost无论如何都被解雇了,当用户按TAB时,或者当用户点击某处时,我找不到它是否被解雇......这是问题的实质。 – DejanLekic 2012-02-12 15:15:24
是的,所以当focuslost被触发时,你会检查你在窗口的任何部分按下鼠标或键时设置的变量。这个变量只记录最后一个鼠标和/或键被按下。你当然必须捕获所有的鼠标和按键,因为点击任何小部件都会让你失去焦点。 – 2012-02-12 15:19:58
这没有帮助,因为按Tab键时,KeyListener什么也不做......如果KeyListener与TAB一起工作,我根本不会问这个问题...... :) – DejanLekic 2012-02-12 15:38:11
*“任何想法,将不胜感激。” *解释用例的这个功能。您想通过了解哪些功能为最终用户提供? – 2012-02-12 15:01:53
安德鲁,感谢您的回复,请参阅*编辑1 *。 – DejanLekic 2012-02-12 15:15:52