java.lang.IllegalStateException when updating JComboBox with setModel()?

依然范特西╮ 提交于 2019-12-02 12:01:04

Wrap your code from the insertUpdate(DocumentEvent e) in SwingUtilities.invokeLater()

Doing this can produce some very weird results. The API is designed to protect against threaded updates and potential modifications that might cause infinite loops

In this case, the text field is modified, the Document is updated, the DocumentListener is notified and you try to change the field again, which would start the cycle again, except the Document has a guard to prevent you from doing just this very thing, hence the Exception.

What you need to do is two things.

  1. You need to update the text field AFTER the DocumentListener has been notified. As has already been stated, this can be achieved by using SwingUtilities.invokeLater
  2. Provide some kind of flag so you don't try and modify your field on events cause by you modifying the field due to DocumentListener events...confused yet?

Basically, this example uses SwingUtilities.invokeLater to update the field AFTER the DocumentListener has completed it's event notifications and a simple boolean flag to provide a means to "ignore" updates that we have triggered...

It's messy, but it will get the job done...mostly...

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.SwingUtilities;
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) {
    }

    boolean beenModified = false;

    @Override
    public void insertUpdate(DocumentEvent e) {

        if (!beenModified) {
            beenModified = true;

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {

                    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();

                    beenModified = false;
                }
            });

        }
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!