我在面板中有一个JComboBox组件,并且附加了ItemListener。但是每次上/下按键后都会被触发(当滚动打开弹出列表时)。我想在用户接受选择后通过按Enter键来更改所选值。
使用鼠标时不是这种情况。当我将鼠标移到组合框的列表上时,突出显示在鼠标指针之后,但是在我按下鼠标按钮之前,所选项目不会更改。我希望键盘具有相同的行为,即通过向上/向下箭头移动突出显示不会更改所选项目,但按Enter键可以。
答案 0 :(得分:19)
我相信你应该能够做到:
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
将comboBox
实例创建为get this functionality 后
答案 1 :(得分:2)
在Java 8中,他们已经修复了这种行为,但只有在你设置了一个UI属性
时才触发UIManager.getLookAndFeelDefaults().put("ComboBox.noActionOnKeyNavigation", true);
答案 2 :(得分:1)
JComboBox.isTableCellEditor
方法适用于列表中的箭头移动,但不适用于KeySelectionManager支持的预先输入。即,您仍然可以为用户键入的每个非导航键获取ActionEvent,因为JComboBox会解释这些字符,以便通过模型进行搜索以移动到(或接近)用户的预期选择。
这个解决方案有一个缺点,就是它改变了鼠标点击的动作命令,这对我来说是一个好的妥协,因为GUI的流程迫使用户将焦点从组合框改变
我最终创建了一个特殊的KeyListener,它依赖于将组合框的默认操作命令从comboBoxChanged
更改为comboBoxMovement
。这是我的组合框全部初始化后我需要的代码行:
setExplicitSelectionManager(myComboBox);
...这里是完成所有工作的方法及其包含的类:
private void setExplicitSelectionManager(JComboBox comboBox) {
class ExplicitSelectionManager implements KeyListener, FocusListener {
private JComboBox src;
private KeyListener superKeyListener;
ExplicitSelectionManager(JComboBox src) {
this.src = src;
// we like what the default key listener does, but not the action command
// it uses for ActionEvents it fires for plain text type-ahead characters
this.superKeyListener = src.getKeyListeners()[0]; // we only have one
src.removeKeyListener(superKeyListener); // will be replace right away, below
}
@Override
public void keyTyped(KeyEvent e) {
// basic combo box has no code in keyTyped
}
@Override
public void keyPressed(KeyEvent e) {
// in the default JComboBox implementation, the KeySelectionManager is
// called from keyPressed. I'm fine with the implementation of
// the default, but I don't want it firing ActionEvents that will cause
// model updates
src.setActionCommand("comboBoxMovement");
this.superKeyListener.keyPressed(e);
src.setActionCommand("comboBoxChanged");
if (e.getKeyCode() == 10) {
src.setSelectedIndex(src.getSelectedIndex());
}
}
@Override
public void keyReleased(KeyEvent e) {
// basic combo box has no code in keyReleased
}
@Override
public void focusGained(FocusEvent e) {
}
@Override
// this will also give us the event we want, if the user decides to Tab out of
// the combo box, instead of hitting Enter
public void focusLost(FocusEvent e) {
src.setSelectedIndex(src.getSelectedIndex());
}
}
ExplicitSelectionManager newSelectionManager = new ExplicitSelectionManager(comboBox);
comboBox.addKeyListener(newSelectionManager);
comboBox.addFocusListener(newSelectionManager);
}
...这里是动作执行方法
private void comboBoxActionPerformed(java.awt.event.ActionEvent evt) {
JComboBox source = (JComboBox) evt.getSource();
// "comboBoxChanged" is the default,
// so any normal JComboBox can also use this action listener
if (evt.getActionCommand().equals("comboBoxChanged")) {
updateModel(source.getName(), (String) source.getSelectedItem());
}
}
答案 3 :(得分:0)
它与ItemListener
的预期行为。只要显示的值发生更改,就会触发事件。根据您的要求,使用ActionListener
。