0

I need to have a comboBox that each time that letter, number or space written (release key), a string is returned with the text write inside the comboBox and without the need of press the Enter key.

Example: I press de “a” key and I release the key “a”, my String need to return “a” Next, I press the “b” key and I realise, my string return “ab” etc.

I use the code from: http://www.java2s.com/Tutorials/Java/Swing_How_to/JComboBox/Add_key_listener_to_Editable_JcomboBox_TextField.htm

And I added in the Key Released event:

Object value = combobox.getSelectedItem();
System.out.println("String: " + value);

In this case that work only if I press the Enter key but I don’t want that

Amy suggestions?

Thanks

import java.awt.FlowLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
//w ww.j  a v  a2  s  .  c om
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class SwingListenerDemo extends JFrame implements KeyListener {
    JComboBox<String> combobox;
  JComboBox<String> combobox1 = new JComboBox(new String[]{"b","b","c"});
  public static void main(String[] args) {
    new SwingListenerDemo();
  }

  private SwingListenerDemo() {
    String[] options = {"Red", "Green", "Blue"};
    combobox = new JComboBox<String>(options);
    combobox.setEditable(true);
    combobox.setSelectedIndex(-1);
  
    combobox1.setEditable(true);
    JTextField editor = (JTextField) combobox.getEditor().getEditorComponent();
    System.out.println("editor" + editor);
    editor.addKeyListener(this);
    setLayout(new FlowLayout());
    add(combobox);
    add(combobox1);
    pack();
    setVisible(true);
  }

  public void keyTyped(KeyEvent arg0) {
    System.out.println("Key Typed " + arg0.getKeyCode());
  }

  public void keyPressed(KeyEvent arg0) {
    System.out.println("Key Pressed " + arg0.getKeyCode());
  }

  public void keyReleased(KeyEvent arg0) {
    System.out.println("Key Released " + arg0.getKeyCode());
    Object value = combobox.getSelectedItem();
    System.out.println("String: " + value);

  }
}
Alberto
  • 13
  • 3
  • 1
    Use an `ActionListener` or `ItemListener` on the combo box to listen for changes to the selected item. Read the Swing tutorial on [How to Use Combo Boxes](https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html) for more information and examples. Or if the item selection isn't changed then use a `DocumentListener` on the text field editor. The tutorial also has a section on `How to Write a DocumentListener`. – camickr May 31 '23 at 01:40
  • If you want to monitor the input been put into the text field, then you will need to make use of a `DocumentListener` and possible supply your own "editor" (in the form of a configured `JTextField`) -DO NOT use a `KeyListener` for this, they are inappropriate for the task – MadProgrammer May 31 '23 at 01:43
  • For [example](https://stackoverflow.com/questions/12118060/add-propertychangelistener-to-jcombobox/12118415#12118415) – MadProgrammer May 31 '23 at 01:47

1 Answers1

1

Don't use a KeyListener for monitor input into a text field, it's not appropriate for the task for a number of reasons.

Instead, make use of a DocumentListener. See How to Write a Document Listener

The following example makes use of a custom ComboBoxEditor, you don't "need" to go to this extend, but it does isolate the core functionality which makes it easier to re-use.

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionListener;
import javax.swing.ComboBoxEditor;
import javax.swing.JComboBox;
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;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setBorder(new EmptyBorder(32, 32, 32, 32));
            JComboBox<String> comboBox = new JComboBox<>(new String[]{"Test", "Testy", "Testing", "More testing"});
            comboBox.setEditor(new MonitorableComboBoxEditor(new MonitorableComboBoxEditor.Observer() {
                @Override
                public void editorTextDidChange(String text) {
                    System.out.println("Text did change " + text);
                }
            }));
            comboBox.setEditable(true);

            add(comboBox);
        }
    }

    public class MonitorableComboBoxEditor implements ComboBoxEditor {

        public interface Observer {
            public void editorTextDidChange(String text);
        }

        private JTextField editor = new JTextField();

        public MonitorableComboBoxEditor(Observer observer) {
            editor.getDocument().addDocumentListener(new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                    observer.editorTextDidChange(editor.getText());
                }

                @Override
                public void removeUpdate(DocumentEvent e) {
                    observer.editorTextDidChange(editor.getText());
                }

                @Override
                public void changedUpdate(DocumentEvent e) {
                    observer.editorTextDidChange(editor.getText());
                }
            });
        }

        @Override
        public Component getEditorComponent() {
            return editor;
        }

        @Override
        public void setItem(Object anObject) {
            if (!(anObject instanceof String)) {
                return;
            }
            editor.setText((String)anObject);
        }

        @Override
        public Object getItem() {
            return editor.getText();
        }

        @Override
        public void selectAll() {
            editor.selectAll();
        }

        @Override
        public void addActionListener(ActionListener l) {
            editor.addActionListener(l);
        }

        @Override
        public void removeActionListener(ActionListener l) {
            editor.removeActionListener(l);
        }
    }
}

Equally, you could make use of factory methods to configure a pre-existing JComboBox, but that's up to you.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366