我试图用setModel()更新JComboBox。但是,它会抛出java.lang.IllegalStateException。 具体来说,我使用JTextField指向JComboBox的可编辑组件,并在每次JTextField接收新输入时更新JComboBox。
谁能告诉我原因?
package ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class TestFrame extends JFrame implements DocumentListener {
private static final long serialVersionUID = 1L;
// tool bar
private JToolBar topToolBar;
private JTextField wordSearchField;
private JComboBox<String> wordSearchTips;
// window size
private static final int width = 700;
private static final int height = 500;
public TestFrame() {
}
public static void main(String[] argv) {
new TestFrame().CreateUI();
}
public void CreateUI() {
setPreferredSize(new Dimension(width, height));
setResizable(false);
setLayout(new BorderLayout());
// bottom
JPanel bottom = new JPanel();
bottom.setPreferredSize(new Dimension(width, 480));
bottom.setLayout(new BorderLayout());
// top
topToolBar = new JToolBar();
topToolBar.setBackground(Color.WHITE);
topToolBar.setPreferredSize(new Dimension(width, 30));
wordSearchTips = new JComboBox<String>();
wordSearchTips.setEditable(true);
wordSearchTips.setSelectedIndex(-1);
wordSearchField = (JTextField) wordSearchTips.getEditor()
.getEditorComponent();
wordSearchField.getDocument().addDocumentListener(this);
topToolBar.add(wordSearchTips);
add(topToolBar, BorderLayout.NORTH);
add(bottom, BorderLayout.SOUTH);
pack();
setVisible(true);
}
@Override
public void changedUpdate(DocumentEvent e) {
}
@Override
public void insertUpdate(DocumentEvent e) {
String keyword = wordSearchField.getText().trim();
DefaultComboBoxModel<String> m = new DefaultComboBoxModel<String>();
;
for (int i = 0; i < 10; i++) {
m.addElement(i + "");
}
wordSearchTips.setModel(m);
wordSearchTips.setSelectedIndex(-1);
((JTextField) wordSearchTips.getEditor().getEditorComponent())
.setText(keyword);
wordSearchTips.showPopup();
}
@Override
public void removeUpdate(DocumentEvent e) {
}
}
以下是例外:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
at javax.swing.text.AbstractDocument.writeLock(Unknown Source)
at javax.swing.text.AbstractDocument.replace(Unknown Source)
at javax.swing.text.JTextComponent.setText(Unknown Source)
at javax.swing.plaf.metal.MetalComboBoxEditor$1.setText(Unknown Source)
at javax.swing.plaf.basic.BasicComboBoxEditor.setItem(Unknown Source)
at javax.swing.JComboBox.configureEditor(Unknown Source)
at javax.swing.plaf.basic.BasicComboBoxUI$Handler.propertyChange(Unknown Source)
at javax.swing.plaf.basic.BasicComboBoxUI$PropertyChangeHandler.propertyChange(Unknown Source)
at javax.swing.plaf.metal.MetalComboBoxUI$MetalPropertyChangeListener.propertyChange(Unknown Source)
at java.beans.PropertyChangeSupport.fire(Unknown Source)
at java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
at java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
at java.awt.Component.firePropertyChange(Unknown Source)
at javax.swing.JComboBox.setModel(Unknown Source)
at ui.TestFrame.insertUpdate(TestFrame.java:94)
at javax.swing.text.AbstractDocument.fireInsertUpdate(Unknown Source)
at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source)
at javax.swing.text.AbstractDocument.insertString(Unknown Source)
at javax.swing.text.PlainDocument.insertString(Unknown Source)
at javax.swing.text.AbstractDocument.replace(Unknown Source)
at javax.swing.text.JTextComponent.replaceSelection(Unknown Source)
at javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction.actionPerformed(Unknown Source)
at javax.swing.SwingUtilities.notifyAction(Unknown Source)
at javax.swing.JComponent.processKeyBinding(Unknown Source)
at javax.swing.JComponent.processKeyBindings(Unknown Source)
at javax.swing.JComponent.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)
答案 0 :(得分:2)
从insertUpdate(DocumentEvent e)
SwingUtilities.invokeLater()
传送您的代码
答案 1 :(得分:2)
这样做会产生一些非常奇怪的结果。 API旨在防止线程更新和可能导致无限循环的潜在修改
在这种情况下,文本字段已修改,Document
已更新,DocumentListener
会收到通知,您尝试再次更改字段,这将再次开始循环,但{{1}除外1}}有一个警卫阻止你做这件事,因此Document
。
你需要做的是两件事。
Exception
后更新文本字段。如前所述,这可以通过使用DocumentListener
SwingUtilities.invokeLater
事件而导致修改字段导致的事件的字段而感到困惑吗?基本上,此示例使用DocumentListener
在SwingUtilities.invokeLater
完成事件通知和简单DocumentListener
标记后更新字段,以便为&#34提供方法;忽略&#34;我们已触发的更新...
它很乱,但它会完成工作......主要是......
boolean