6

Is there a good(and easy) way to make a JCombobox look like a JTextField? By this I mean there should not be a dropdown button, but when the user enters something it should show multible results.

Basically the same way google, youtube, facebook etc. works.

Mark
  • 28,783
  • 8
  • 63
  • 92
Mads Andersen
  • 3,123
  • 5
  • 38
  • 44

3 Answers3

6
JComboBox comboBox = new JComboBox();
comboBox.setUI(new BasicComboBoxUI() {
    @Override
    protected JButton createArrowButton() {
        return new JButton() {
            @Override
            public int getWidth() {
                return 0;
            }
        };
    }
});

Making getWidth() return 0 ensures that:
a) the button is not shown
b) no space is reserved for it, letting you type in the whole field

I found that I had to do invoke .setUI() via SwingUtilities.invokeLater(), but depending on the structure of your code, you might not have to.

If you want autocomplete, add some items to the combo box, and use AutoCompleteDecorator.decorate(comboBox). The AutoCompleteDecorator class is part of SwingX, as previously mentioned.

This might make your box look weird when using another L&F, so you will have to choose which CombiBoxUI to instantiate, to get the right look.

If you do not want the drop-down to appear when there is nothing in the combo box, override this method in the BasicComboBoxUI as well:

@Override
public void setPopupVisible(JComboBox c, boolean v) {
    // keeps the popup from coming down if there's nothing in the combo box
    if (c.getItemCount() > 0) {
        super.setPopupVisible(c, v);
    }
}
Markus Jevring
  • 832
  • 1
  • 11
  • 17
  • Is there a way to make it look just like a text field with an arrow? i tried your solution but it looks weird and the combobox option just comes written directly and when you start writing in it it replaces the text you are writing with the option directly which is not what i'm looking for, i want the user to be able to write anything he wants in the combobox and the options show under that text for the user to choose. – Gherbi Hicham Jun 13 '16 at 12:46
2

I have a very similar problem, I don't care about the popup arrow, but I need to control the text appearance when the component is disabled.

I want to show the current value, but disable list selection/editing. The only way to get this behavior with JComboBox is to use comboBox.setEnabled(false); which makes the text an unreadable light grey.

I created a ComoBoxUIDecorator, and intercepted some of the paint methods. This has exactly the right effect -- the arrow appears greyed out while the current value appears in black and readable (as if enabled).

public class ComboBoxUIDecorator extends ComboBoxUI {
 private ComboBoxUI m_parent;

 public ComboBoxUIDecorator(ComboBoxUI x) {
  m_parent = x;
 }
 ...
 public boolean isFocusTraversable(JComboBox c) {
  return m_parent.isFocusTraversable(c);
 }

 public void paint(Graphics g, JComponent c) {
  c.setEnabled(m_displayEnabledState);
  m_parent.paint(g, c);
  c.setEnabled(m_realEnabledState);
 }
}

You might try a similar approach; If you could find the arrow button, you could paint over the arrow after invoking m_parent.paint()

Justin
  • 4,437
  • 6
  • 32
  • 52
2

Do you mean that you want it to behave like a text field that autocompletes against previously entered values? SwingX includes support for adding autocompletion to text components.

Another library you could look at is JIDE Common Layer. Their IntelliHints functionality might be what you are looking for. There is a demo you can download from here.

Mark
  • 28,783
  • 8
  • 63
  • 92
  • I already use a similar library called glazedList. The problem is that if I add autocompletion to a JTextField it only autocompletes one result. Try fx to write "stackoverflow" in google without searching. You will get multible results(dropdown menu) but you wont see a button like on a JCombobox. Hope this makes sense :) – Mads Andersen May 04 '09 at 23:12
  • That makes sense. I have updated my answer with another suggestion. – Mark May 05 '09 at 08:53