Could I to develop a dynamic popup of a JCombobox editable, that changes the content while the user insert or remove text?

2 weeks ago 19
ARTICLE AD BOX

I have some problems to set the popup of my JComboBox in java 17. I'm developing my app with windowsBuilder and I want to the popup is updating while the user insert o remove text, only appearing the items that match with the principle of the text introduced by the user. If the string is empty, the popup is setting in the original menu, in all the cases the menu is visible. for that, I try to modify the model with the setModel() method in my comboBox, into a DocumentListener in the jTextField intern of the JcomboBox (I called editor), but appears the exception:

"Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification"

First, I thought to search the guides of my professor, but there aren't any examples about a dynamic JcomboBox. Also, I have searched other forums and even in this one, the only thing I managed to do is try it with MutableComboBoxModel, which I couldn't load in Java even using the shortcut Ctrl + shift + O (I use Eclipse). I tried watching YouTube videos and there is nothing like this. I would prefer if you could help me with this please, I am using Windows 11,

Below is the code, it is in the prove.java document.

The traces of the error and the code are the following (I got the error either I click in the JcomboBox and I edit the comboBox):

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification at java.desktop/javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1372) at java.desktop/javax.swing.text.AbstractDocument.replace(AbstractDocument.java:688) at java.desktop/javax.swing.text.JTextComponent.setText(JTextComponent.java:1725) at java.desktop/javax.swing.plaf.metal.MetalComboBoxEditor$1.setText(MetalComboBoxEditor.java:63) at java.desktop/javax.swing.plaf.basic.BasicComboBoxEditor.setItem(BasicComboBoxEditor.java:93) at java.desktop/javax.swing.JComboBox.configureEditor(JComboBox.java:1439) at java.desktop/javax.swing.plaf.basic.BasicComboBoxUI$Handler.propertyChange(BasicComboBoxUI.java:1812) at java.desktop/javax.swing.plaf.basic.BasicComboBoxUI$PropertyChangeHandler.propertyChange(BasicComboBoxUI.java:704) at java.desktop/javax.swing.plaf.metal.MetalComboBoxUI$MetalPropertyChangeListener.propertyChange(MetalComboBoxUI.java:224) at java.desktop/java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:343) at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:335) at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:268) at java.desktop/java.awt.Component.firePropertyChange(Component.java:8717) at java.desktop/javax.swing.JComboBox.setModel(JComboBox.java:362) at cfgs.prove$3.removeUpdate(prove.java:136) at java.desktop/javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:285) at java.desktop/javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:652) at java.desktop/javax.swing.text.AbstractDocument.remove(AbstractDocument.java:620) at java.desktop/javax.swing.text.AbstractDocument.replace(AbstractDocument.java:696) at java.desktop/javax.swing.text.JTextComponent.setText(JTextComponent.java:1725) at java.desktop/javax.swing.plaf.metal.MetalComboBoxEditor$1.setText(MetalComboBoxEditor.java:63) at cfgs.prove$4.mousePressed(prove.java:156) at java.desktop/java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:288) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6618) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3398) at java.desktop/java.awt.Component.processEvent(Component.java:6386) at java.desktop/java.awt.Container.processEvent(Container.java:2266) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4572) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) package cfgs; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.JLabel; import javax.swing.SwingConstants; import java.awt.Font; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.regex.Pattern; import javax.swing.JComboBox; import javax.swing.DefaultComboBoxModel; public class prove extends JFrame { private static final long serialVersionUID = 1L; private JPanel contentPane; protected JComboBox<String> comboBox; protected static String[] usuarios = {"James", "Ana", "Andres", "Maria", "John", "gustavo"}; protected static DefaultComboBoxModel<String> comb; public static String[] FiltrarUsuarios(String str) { int i = 1, N = usuarios.length; ArrayList<String> filtrados = new ArrayList<String>(); Pattern filtro = Pattern.compile("^"+str+".*"); //coincide con lo que empieza con este string (str). comb = new DefaultComboBoxModel<String>(usuarios); String elemento; String[] retorno; while (i<N) { elemento = comb.getElementAt(i); if (filtro.matcher(elemento).matches()) //colocar el objeto filtrados.add(elemento); i++; } N = filtrados.size(); i = 1; //reutilizo ambas variables i, N. retorno = new String[++N]; retorno[0] = str; while (i<N) { retorno[i] = filtrados.get(i-1); i++; } return retorno; } /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { prove frame = new prove("Introduzca el usuario", true); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public prove(String mensaje, boolean bool) { comb = new DefaultComboBoxModel<String>(usuarios); setTitle("Dynamic comboBox."); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JLabel lblNewLabel = new JLabel("Dynamic JComboBox"); lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 17)); lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER); lblNewLabel.setBounds(116, 11, 184, 39); contentPane.add(lblNewLabel); JLabel a_message = new JLabel(mensaje); a_message.setHorizontalAlignment(SwingConstants.CENTER); a_message.setFont(new Font("Tahoma", Font.BOLD, 14)); a_message.setBounds(116, 83, 184, 39); contentPane.add(a_message); JComboBox<String> comboBox = new JComboBox<String>(); comboBox.setModel(new DefaultComboBoxModel<String>(usuarios)); comboBox.setVisible(bool); comboBox.setModel(comb); comboBox.setEditable(true); comboBox.setFont(new Font("Tahoma", Font.BOLD, 13)); comboBox.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { new DefaultComboBoxModel<String>(usuarios); comboBox.setModel(comb); comboBox.setPopupVisible(false); } }); JTextField editor = (JTextField) comboBox.getEditor().getEditorComponent(); //hecho un casteo a Jtextfield para acceder al contenido con el método getText(). editor.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { String src = editor.getText(); String[] lista; System.out.println("el contenido es:"+src); lista = FiltrarUsuarios(src); comb = new DefaultComboBoxModel<String>(lista); //usuarios comboBox.setModel(comb); comboBox.setPopupVisible(false); } @Override public void removeUpdate(DocumentEvent e) { String src = editor.getText(); String[] lista; System.out.println("Ahora es borrar contenido. El contenido es:"+src); if (src.equals("")) { comb = new DefaultComboBoxModel<String>(usuarios); comboBox.setModel(comb); comboBox.setPopupVisible(false); } else { lista = FiltrarUsuarios(src); comb = new DefaultComboBoxModel<String>(lista); //usuarios comboBox.setModel(comb); comboBox.setPopupVisible(false); } } @Override public void changedUpdate(DocumentEvent e) { System.out.println("Formato cambiado"); } }); editor.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { editor.setText(""); } }); comboBox.setBounds(116, 133, 184, 39); contentPane.add(comboBox); } }
Read Entire Article