16

I keep searching and it seems like everybody is using only the JComboBox#getSelectedItem. But my combo box is editable and the user can enter anything. The getSelectedItem method returns one of the actual items in the combo box, not a string entered in the field.

image description

If my box contains "Bar" and "Item" and user enters "Foo", I want to get "Foo"!

Why getSelectedItem does not work

It was pointed out that getSelectedItem does also return the string entered. It was not pointed out though, that this only works after the user stops editing the field. I attached these event listeners:

Component[] comps = input.getComponents();
//Third is the text field component
comps[2].addKeyListener(new KeyListener() {
  public void keyTyped(KeyEvent e) {
    doSomething();
  }
});
//Also fire event after user leaves the field
input.addActionListener (new ActionListener () {
    @Override
    public void actionPerformed(ActionEvent e) {
      doSomething();
    }
});

And this were the results:

KeyEvent:
 JComboBox.getEditor().getItem() = 6  
 JComboBox.getSelectedItem()     = null
KeyEvent:
 JComboBox.getEditor().getItem() = 66
 JComboBox.getSelectedItem()     = null
KeyEvent:
 JComboBox.getEditor().getItem() = 666
 JComboBox.getSelectedItem()     = null
ActionEvent:
 JComboBox.getEditor().getItem() = 6666
 JComboBox.getSelectedItem()     = 6666

As you can see, the action event listener could capture the value, but the key event could not.

Community
  • 1
  • 1
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • `getSelectedItem` seems to work just fine for me. Maybe you should show us some code. – tobias_k Mar 17 '15 at 16:46
  • Actually, could you post the code that is working for you somewhere? – Tomáš Zato Mar 17 '15 at 16:48
  • Also, looks like it's a duplicate of: https://stackoverflow.com/questions/10072335/get-input-values-from-jcombobox – uraimo Mar 17 '15 at 18:15
  • I have clarified why does not `getSelectedItem` work. The likned duplicate question does ask "*Get input **values** from JComboBox*" which makes the impression it's asking for something else. Maybe that's why I didn't find it. – Tomáš Zato Mar 17 '15 at 19:53

2 Answers2

22

This way: combobox.getEditor().getItem(). Nice drawing.

uraimo
  • 19,081
  • 8
  • 48
  • 55
1

Maybe there is something wrong in the way you are using getSelectedItem. For me, this seems to work just fine:

JComboBox<String> combo = new JComboBox<>(new String[] {"bar", "item"});
combo.setEditable(true);

JButton button = new JButton("Get");
button.addActionListener((ActionEvent e) -> {
    System.out.println(combo.getSelectedItem());
});

JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.getContentPane().add(combo);
frame.getContentPane().add(button);
frame.pack();
frame.setVisible(true);

If you click the button after selecting one of the predefined items, it prints that item, and if you enter some text and then press the button, it prints that text.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • 1
    I researched this and it turned out that your solution doesn't work if you try to get the value while it's being changed (field has focus). I retrieve the value of the field after every keypress event. – Tomáš Zato Mar 17 '15 at 19:46
  • 2
    @TomášZato, this is a year late, but I'll correct anyways for future reference: When you say "I retrieve the value of the field after every keypress event", I hope you don't mean "keypress event" literally. Triggering based on key events can be harder to implement, will not always work and will lead to problems. Instead, attach a `DocumentListener` to the `JComboBox`'s underlying `ComboBoxEditor` component's underlying `Document`: `((JTextComponent) yourComboBox.getEditor().getEditorComponent()).getDocument().addDocumentListener(yourDocumentListener);` – CosmicGiant Sep 19 '16 at 22:51
  • I also second what Tomás said about this not working while the text is being typed. The change only gets consolidated to the `SelectedItem` upon the equivalent of `ActionPerformed`, in other words, only when [Enter] is pressed, or when the `JComboBox` loses focus. – CosmicGiant Sep 19 '16 at 22:55
  • @AlmightyR Apparently I use `itemStateChanged` and `actionPerformed`: https://github.com/Darker/auto-client/blob/4dd2f07ba2a05a2612d5c2a919669b7942b4171d/src/cz/autoclient/settings/input_handlers/InputJComboBox.java#L42 – Tomáš Zato Sep 20 '16 at 08:55
  • @TomášZato Yea, you should probably change that. State changes can happen for things that are not changes in input, which means you are calling that `changed()` method a lot more than you need. And although I'm not sure, since the state change listener is there, it's also likely that your `ActionPerformed` is being redundant, as a state change might be and probably is triggered by `ActionPerformed` anyway. --- Even if that isn't the case, a `DocumentListener` is still the right way to go, as you only need one listener instead of two, making things easier to manage, refactor, etc... – CosmicGiant Sep 20 '16 at 16:19
  • One reason to use a `DocumentListener` (as suggested by AlmightyR) instead of handling key events is that it catches all modifications, even those made by pasting or deleting text using a pointing device and changes made by the program itself. – Martin Aug 03 '17 at 09:55