I need to update the items of JCombobox from the database during runtime. I had made the JCombobox editable and what i need to do is type something in the editable combobox and search the database and only display the items matching the text. For example there are if i type "ap" in the editbox of JCombobox then i want only the items containing "ap" like "apes" and "apple" i can have them in the console during runtime but when i try to set those item as an items of Jcombobox i am getting error something including "MUtation....". how can i do this . Thanx in advance

Recommended Answers

All 17 Replies

Why don't you post the entire error message? And some code? You generally do it like this:

cmb.removeAllItems();
cmb.addItem("item 1");
cmb.addItem("item 2");
...

If there's a change of having duplicate strings, create a class and override the toString() method, or use anonymous classes, like:

cmb.removeAllItems();
cmb.addItem(new Object() { public String toString() { return "item 1"; } });
cmb.addItem(new Object() { public String toString() { return "item 2"; } });
...

SEARCH:chicke
SEARCHED ITEM:chicken
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification

 at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1323)
        at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:644)
        at javax.swing.text.JTextComponent.setText(JTextComponent.java:1693)
        at javax.swing.plaf.metal.MetalComboBoxEditor$1.setText(MetalComboBoxEditor.java:44)
        at javax.swing.plaf.basic.BasicComboBoxEditor.setItem(BasicComboBoxEditor.java:60)
        at javax.swing.JComboBox.configureEditor(JComboBox.java:1383)
        at javax.swing.plaf.basic.BasicComboBoxUI$Handler.contentsChanged(BasicComboBoxUI.java:1817)
        at javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:100)
        at javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:88)
        at javax.swing.DefaultComboBoxModel.removeElementAt(DefaultComboBoxModel.java:140)
        at javax.swing.JComboBox.removeItemAt(JComboBox.java:739)
        at ui.restuarant.ExternalOrderPanel$1.removeUpdate(ExternalOrderPanel.java:64)
        at javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:243)
        at javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:608)
        at javax.swing.text.AbstractDocument.remove(AbstractDocument.java:576)
        at javax.swing.text.DefaultEditorKit$DeletePrevCharAction.actionPerformed(DefaultEditorKit.java:1045)
        at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1633)
        at javax.swing.JComponent.processKeyBinding(JComponent.java:2839)
        at javax.swing.JComponent.processKeyBindings(JComponent.java:2874)
        at javax.swing.JComponent.processKeyEvent(JComponent.java:2802)
        at java.awt.Component.processEvent(Component.java:6040)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
        at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
        at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:676)
        at java.awt.Component.dispatchEventImpl(Component.java:4502)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Window.dispatchEventImpl(Window.java:2475)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)*Emphasized Text Here*

This is the error i get when i try to change the items during runtime plzzz help

can you show the code where that exception is thrown?

 final JTextComponent tc = (JTextComponent) itemNameSelector.getEditor().getEditorComponent();
        tc.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                try {
                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                    rest.searchMenuItem(searchingText);
                    itemNameSelector.addItem(searchingText);
                    itemNameSelector.revalidate();

                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public void removeUpdate(DocumentEvent e) {
                try {
                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                    rest.searchMenuItem(searchingText);
                    itemNameSelector.removeItemAt(0);
                    itemNameSelector.revalidate();


                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

Here searchingText is a String that is typed in Editable Combobox and according to that String i need to update the items of that combobox. But when i try this code i get the above error. But i can get the desired item names on my console.

The problem seems to be that the document is locked when the listener is called, so when you try to update the document you can't get the lock to write to it. The solution, if you want to keep it working the same way, is to use SwingUtilities.invokeLater to run the update after your listener has finished.

You want to have a look at this thread. I don't have time to look at the solutions now, but they may be of some help.

will u please show me where can i call that SwingUtilities.invokeLater method i have done like this but its not working.

 final JTextComponent tc = (JTextComponent) itemNameSelector.getEditor().getEditorComponent();
        tc.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                try {
                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);

                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public void removeUpdate(DocumentEvent e) {
                try {
                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                    //rest.searchMenuItem(searchingText);
                    //  itemNameSelector.removeItemAt(0);
                    // itemNameSelector.revalidate();


                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public void changedUpdate(DocumentEvent e) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });

        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                rest.searchMenuItem(searchingText);
                itemNameSelector.addItem(searchingText);
                itemNameSelector.revalidate();
                itemNameSelector.repaint();

            }
        });

           final JTextComponent tc = (JTextComponent) itemNameSelector.getEditor().getEditorComponent();
            tc.getDocument().addDocumentListener(new DocumentListener() {

                public void insertUpdate(DocumentEvent e) {
                    try {
                        searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                        System.out.println("SEARCH:" + searchingText);

                    } catch (BadLocationException ex) {
                        Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

                public void removeUpdate(DocumentEvent e) {
                    try {
                        searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                        System.out.println("SEARCH:" + searchingText);
                        //rest.searchMenuItem(searchingText);
                        //  itemNameSelector.removeItemAt(0);
                        // itemNameSelector.revalidate();


                    } catch (BadLocationException ex) {
                        Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

                public void changedUpdate(DocumentEvent e) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });

            javax.swing.SwingUtilities.invokeLater(new Runnable() {

                public void run() {
                    rest.searchMenuItem(searchingText);
                    itemNameSelector.addItem(searchingText);
                    itemNameSelector.revalidate();
                    itemNameSelector.repaint();

                }
            });

Look at all the places where you try to change the contents and replace the remove or add statements with an invokeLater that runs the remove or add later.

I modified my code like this but it goes on adding items infinitely and also the editor pane is filled with "word" the w is typed.

final Runnable run1 = new Runnable() {

            public void run() {
                itemNameSelector.removeAllItems();
                rest.searchMenuItem(searchingText);
                int i = RestuarantServiceImpl.menus.size();
                for (int k = 1; k < i; k++) {
                    itemNameSelector.addItem(RestuarantServiceImpl.menus.get(k));
                }
                itemNameSelector.revalidate();
                itemNameSelector.repaint();
            }
        };

        final JTextComponent tc = (JTextComponent) itemNameSelector.getEditor().getEditorComponent();
        tc.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                try {

                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                     javax.swing.SwingUtilities.invokeLater(run1);


                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public void removeUpdate(DocumentEvent e) {
                try {

                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                      javax.swing.SwingUtilities.invokeLater(run1);

                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

By updating the document you are triggering your listener - which updates the document - ...
One way to avoid this is to have a shared boolean that you set when you do a programmatic update (ie in the invokeLater's run) then test this in the document listener to decide whether to do anything (and, of course, reset the boolean).
(I'm going offline now, so you may need some trial-and-error to get it right.)

i'm not getting the result will u please suggest me using some code.

i'm not getting the result

What result are you not getting? What code did you write?

i wrote exactly the same as above mentioned code

So you haven't tried to implement what I suggested?
OK.

final Runnable run1 = new Runnable() {

            public void run() {
                while (sts == true) {
                    itemNameSelector.removeAllItems();
                    rest.searchMenuItem(searchingText);
                    int i = RestuarantServiceImpl.menus.size();
                    for (int k = 1; k < i; k++) {
                        itemNameSelector.addItem(RestuarantServiceImpl.menus.get(k));
                    }

                    sts = false;
                    itemNameSelector.revalidate();
                    itemNameSelector.repaint();
                }
            }
        };



        final JTextComponent tc = (JTextComponent) itemNameSelector.getEditor().getEditorComponent();
        tc.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                try {
                    sts = true;
                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                    javax.swing.SwingUtilities.invokeLater(run1);



                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public void removeUpdate(DocumentEvent e) {
                try {
                    sts = true;
                    searchingText = e.getDocument().getText(0, e.getDocument().getLength());
                    System.out.println("SEARCH:" + searchingText);
                    javax.swing.SwingUtilities.invokeLater(run1);

                } catch (BadLocationException ex) {
                    Logger.getLogger(ExternalOrderPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            public void changedUpdate(DocumentEvent e) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });

        this is how i tried to program by usinbg boolean as u suggested but  its not working. Whenever i press C, the 1st word of arraylist is automatically completed in that searchbox and then when i try to delete the letters i am not able to delete them. please help

Your while loop in run1 will never terminate, so your code is stuck in an infinite loop.

Your document listener will be called when the document changes. This may be because the user has typed something, or becuase your code has changed it. If the user has changed it you want to perform yopur updates, but not in response to your code changing it.
So you need a shared boolean.
When you update the document (ie in your run1 class) you set the boolean to show that this is a programmatic change, not a user change.
When you respond to changes you check the boolean. If it's fase then you are responding to user input and can continue as normal. If it;s true you are responding to a programmed change, and don't want to do anything else (except reset the boolean).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.