java 我如何知道可编辑 JComboBox 的文本何时发生更改?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1252698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I know when the text of an editable JComboBox has been changed?
提问by Lawrence Dol
I have an editableJComboBox where I want to take some action whenever the text is changed, either by typing or selection. In this case, the text is a pattern and I want to verify that the pattern is valid and show the matches that result in some test data.
我有一个可编辑的JComboBox,我想在文本更改时采取一些操作,无论是通过键入还是选择。在这种情况下,文本是一个模式,我想验证该模式是否有效并显示导致某些测试数据的匹配项。
Having done the obvious, attach an ActionHandler, I have found that, for typing, the event seems to fire unreliably, at best (selection is fine). And when it doesfire as a result of typing, the text retrieved (using getEditor().getItem(), since getSelectedItem() only gets the text when it was selected from the list) seems to be the text as it was when the last event was fired - that is, it's always missing the character was typed immediately before the action event was fired.
做完显而易见的事情,附加一个 ActionHandler,我发现,对于打字,事件似乎不可靠地触发,充其量(选择很好)。当它确实因键入而触发时,检索到的文本(使用 getEditor().getItem(),因为 getSelectedItem() 仅在从列表中选择文本时才获取文本)似乎是文本最后一个事件被触发 - 也就是说,它总是缺少在触发动作事件之前立即输入的字符。
I was expecting the action event to fire after some short delay (500ms to 1 second), but it seems immediately fired upon keying (if it is fired at all).
我期待动作事件在一些短暂的延迟(500 毫秒到 1 秒)后触发,但它似乎在键控时立即触发(如果它被触发的话)。
The only workable alternative I can think of is to simply start a 1 second timer on focus-gained, killing it on focus-lost and doing the work as the timer action if the content is different from last time.
我能想到的唯一可行的替代方法是简单地在获得焦点时启动一个 1 秒的计时器,在失去焦点时杀死它,如果内容与上次不同,则将其作为计时器操作来执行。
Any thoughts or suggestions?
有什么想法或建议吗?
The code snippets are not particularly interesting:
代码片段并不是特别有趣:
find.addActionListener(this);
...
public void actionPerformed(ActionEvent evt) {
System.out.println("Find: "+find.getEditor().getItem());
}
回答by Dave Ray
The action listener is typically only fired when you hit enter, or move focus away from the editor of the combobox. The correct way to intercept individual changes to the editor is to register a document listener:
动作侦听器通常仅在您按 Enter 键或将焦点从组合框的编辑器移开时才会触发。拦截对编辑器的个别更改的正确方法是注册一个文档侦听器:
final JTextComponent tc = (JTextComponent) combo.getEditor().getEditorComponent();
tc.getDocument().addDocumentListener(this);
The DocumentListener interfacehas methods that are called whenever the Document backing the editor is modified (insertUpdate, removeUpdate, changeUpdate).
所述的DocumentListener接口具有每当文档衬板编辑器被修改(中的insertUpdate,中的removeUpdate,changeUpdate)被调用的方法。
You can also use an anonymous class for finer-grained control of where events are coming from:
您还可以使用匿名类对事件的来源进行更细粒度的控制:
final JTextComponent tcA = (JTextComponent) comboA.getEditor().getEditorComponent();
tcA.getDocument().addDocumentListener(new DocumentListener() {
... code that uses comboA ...
});
final JTextComponent tcB = (JTextComponent) comboB.getEditor().getEditorComponent();
tcB.getDocument().addDocumentListener(new DocumentListener() {
... code that uses comboB ...
});
回答by ungalcrys
You can use somthing like this:
你可以使用这样的东西:
JComboBox cbListText = new JComboBox();
cbListText.addItem("1");
cbListText.addItem("2");
cbListText.setEditable(true);
final JTextField tfListText = (JTextField) cbListText.getEditor().getEditorComponent();
tfListText.addCaretListener(new CaretListener() {
private String lastText;
@Override
public void caretUpdate(CaretEvent e) {
String text = tfListText.getText();
if (!text.equals(lastText)) {
lastText = text;
// HERE YOU CAN WRITE YOUR CODE
}
}
});
回答by isaac
this sounds like the best solution
这听起来是最好的解决方案
jComboBox.getEditor().getEditorComponent().addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) { //add your hadling code here:
} });

