我有一个面板,其中包含几个文本字段和一个用于执行搜索的可编辑JComboBox
。我希望所有这些都像我按下回车键时按下下面的搜索按钮一样。这适用于JTextField
ActionListener
的{{1}}。但是,我只希望JComboBox
在按下输入时开始搜索,并且没有显示下拉列表。即如果用户按下Enter键以在下拉列表中选择一个选项,则不会发生任何事情。
我将如何实现此行为?
我尝试检查getActionCommand()
,并在事件触发时显示"comboBoxEdited"
或"comboBoxChanged"
。选择选项后按Enter键时以及在可编辑字段中按Enter键时会触发"comboBoxEdited"
。在选项之间移动时,以及在编辑文本后按下输入时"comboBoxChanged"
之前,"comboBoxEdited"
会被触发。
我尝试了一个丑陋的黑客,我存储了之前的ActionCommand
,但它并不完美,因为用户在手动输入文本后必须按两次输入。
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("comboBoxEdited") &&
!combohack.equals("comboBoxChanged")) {
combohack="";
//PERFORM SEARCH!
}
combohack=e.getActionCommand();
}
我进一步尝试通过添加KeyListener
来重置字符串,以便在按下实际字母时重置字符串,但我没有帮助。
有什么想法吗?
答案 0 :(得分:1)
好的,这有点沉重,但这样做会将KeyEvent.VK_ENTER
Action
替换为我们自己的Action
基本上,当用户按下 Enter 键时,会通知Action
,但组合框不通知(因此JComboBox
不会触发{ {1}}对于它 - 但将用于选择更改)
ActionEvent
感谢您的努力!它并不像我想要的那样真正起作用。当按下[Enter]以选择突出显示的项目时,它仍会使用“comboBoxEdited”触发事件,而不是仅关闭下拉列表,而在编辑器中保留所选文本。它只应在下拉菜单关闭并且用户按下[Enter]时触发事件。所以[Enter]选择一个项目,再次按[Enter]激活该动作。
所以,我终于在Windows机器上运行代码了,基本上,在import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ComboBoxEditor;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
final JComboBox<String> cb = new JComboBox<>(new String[]{"Apples", "Bananas", "Pears"});
cb.setEditable(true);
SimpleComboBoxEditor editor = new SimpleComboBoxEditor();
InputMap im = editor.getInputMap();
ActionMap am = editor.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
am.put("enter", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!cb.isPopupVisible()) {
System.out.println("Editor did action");
}
cb.hidePopup();
}
});
cb.setEditor(editor);
cb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Combobox did action");
}
});
add(cb);
}
public class SimpleComboBoxEditor extends JTextField implements ComboBoxEditor {
@Override
public Component getEditorComponent() {
return this;
}
@Override
public void setItem(Object anObject) {
if (anObject != null) {
setText(anObject.toString());
} else {
setText(null);
}
}
@Override
public Object getItem() {
return getText();
}
}
}
}
的密钥绑定中,我检查了Action
,当它不是时,它会打印出来“编辑做了动作”事件,否则它什么都不做
答案 1 :(得分:-1)
实际上有一个相当简单和优雅的解决方案:
combo.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER && !combo.isPopupVisible()) {
System.out.println("SEARCH!");
}
}
});
请注意,如果KeyListener
直接添加到JComboBox
,则EditorComponent
无法使用,但必须添加到<form method="post"
<input type="text" name="search_keyword">
<input type="submit" name="button_search">
</form>
。