【发布时间】:2016-03-17 14:39:29
【问题描述】:
我需要实现我的自定义 DefaultComboboxModel。这样做的原因是每次我调用
DefaultComboBoxModel model = (DefaultComboBoxModel)getModel();
model.removeAllElements();
或
model.addElement(Object);
或
model.insertElementAt(Object,int)
我看到它会自动触发 ItemStateChanged 事件。这导致一些随机项目自动从列表中选择。这不是我想要的,因为它使用随机选定的项目填充可编辑的 JTextField。
这是我在使用自定义 Itemlistener 中的 Thread.dumpStack() 进行调试时看到的堆栈跟踪,我在调用上述方法时看到:
at javax.swing.JComboBox.fireItemStatehanged(Unknown source)
at javax.swing.JComboBox.selectedItemChanged(Unknown source)
at javax.swing.JComboBox.contentsChanged(Unknown source)
at javax.swing.JComboBox.fireContentsChanged(Unknown source)
at javax.swing.JComboBox.setSelectedItem(Unknown source)
at javax.swing.JComboBox.addElement(Unknown source)
我已经尝试在更新模型之前和更新模型之后使用 setSelectedIndex(-1),但同样的问题。我想拥有我的自定义模型是要走的路。
问题是如何实现我的自定义组合框模型?我只是扩展 DefaultComboBoxModel 吗?我是否必须覆盖 DefaultComboBoxMode 中的所有方法?
以下是我目前所拥有的。但是,如果您在下面看到,我没有参考实际的 Vector 列表来删除该项目。如果我在自定义 AutocompleteComboBoxModel 中声明了 Vector 列表字段,那么我是否需要重写所有方法以避免其他 SWING 代码引用超类中的 Vector?
请记住,我的目标是绝不允许模型自动调用 setSelectedItem(Object),因为这似乎会导致问题,除非有更好的方法来做到这一点。
public class AutocompleteComboBoxModel extends DefaultComboBoxModel{
public void removeElementAt(int index){
list.removeElementAt(index);
fireIntervalRemoved(this, index, index);
}
}
这也是我调用模型操作方法的方式:
public class AutocompleteDocumentListener implementts DocumentListener{
JTextField tf;
public AutocompleteDocumentListener (JTextfield tf){
this.tf = tf;
}
@Override
public void changedUpdate(DocumentEvent e){
}
@Override
public void insertUpdate(DocumentEvent e){
update();
}
@Override
public void removeUpdate(DocumentEvent e){
update();
}
public void update(){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
performSearch(tf.getText());//Search user input
}
)
}
}
编辑:只想提一下,这种奇怪的行为仅在我输入非常快时才会发生。如果我输入缓慢,则 SWING 不会自动选择随机项目。那么,如果我使用 SwingUtlities.invokeLater,为什么在快速打字时会出现这种情况呢?目前当 SWING 调用 setSelectedItem(Object) 时,这个触发的事件会在其他的 invokeLater 请求之前执行吗?
编辑:我正在删除 ItemListener 并且仍然无法正常工作。然后我继续删除 JComboBox KeyListeners、ActionListeners、ComponentListeners 和 FocusListeners,但它仍然自动选择 Item。似乎在 invokeLater 完成后的某个时间,我看到该项目被选中,可能是因为我仍在 JTextField 上输入:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Unknown Source)
at com.artificialmed.coderdx.encoder.TermSelectionListener.itemStateChanged(TermSelectionListener.java:23)
at javax.swing.JComboBox.fireItemStateChanged(Unknown Source)
at javax.swing.JComboBox.selectedItemChanged(Unknown Source)
at javax.swing.JComboBox.contentsChanged(Unknown Source)
at javax.swing.AbstractListModel.fireContentsChanged(Unknown Source)
at javax.swing.DefaultComboBoxModel.setSelectedItem(Unknown Source)
at javax.swing.JComboBox.setSelectedItem(Unknown Source)
at javax.swing.JComboBox.setSelectedIndex(Unknown Source)
at javax.swing.JComboBox.selectWithKeyChar(Unknown Source)
at javax.swing.plaf.basic.BasicComboBoxUI$Handler.keyPressed(Unknown Source)
at java.awt.Component.processKeyEvent(Unknown Source)
at javax.swing.JComponent.processKeyEvent(Unknown Source)
at javax.swing.JComboBox.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
提前致谢。
【问题讨论】: