Adding a watermark to an empty JCombobox

java, jcombobox, swing

Solution

Note:

Check out Text Prompt for a more complete implementation of the code below with more features.

Here's something simple I threw together. I'm sure you can tidy it up. Since the code works on a JTextField, you would need to get the editor of the combobox. I no nothing about how Glazed lists is implemented so I'm just guessing it will work for you.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;

public class TextPrompt extends JLabel
    implements FocusListener, DocumentListener
{
    private JTextComponent component;
    private Document document;

    public TextPrompt(String text, JTextComponent component)
    {
        this.component = component;
        document = component.getDocument();

        setText( text );
        setFont( component.getFont() );
        setBorder( new EmptyBorder(component.getInsets()) );

        component.addFocusListener( this );
        document.addDocumentListener( this );

        component.add( this );
    }

    public void checkForPrompt()
    {
        if (document.getLength() == 0)
            setSize( component.getSize() );
        else
            setSize(0, 0);
    }

//  Implement FocusListener

    public void focusGained(FocusEvent e)
    {
        checkForPrompt();
    }

    public void focusLost(FocusEvent e)
    {
        setSize(0, 0);
    }

//  Implement DocumentListener

    public void insertUpdate(DocumentEvent e)
    {
        checkForPrompt();
    }

    public void removeUpdate(DocumentEvent e)
    {
        checkForPrompt();
    }

    public void changedUpdate(DocumentEvent e) {}

    public static void main(String[] args)
    {
        JPanel panel = new JPanel();
        JTextField tf1 = new JTextField(10);
        panel.add(tf1);
        JTextField tf2 = new JTextField(10);
        panel.add(tf2);

        new TextPrompt("First Name", tf1);
        new TextPrompt("Last Name", tf2);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

Problem

I'm trying to reproduce the behavior of the search field of Firefox or Safari, or the search field of `stackoverflow.com` on the top right of this page. I mean, when there is no text on the editable `JComboBox`, an instruction text is displayed, like `"Type here"` or whatever. When the `JComboBox` is focused the text is removed. If the focus is lost with no text typed, the instruction text comes back.

Original source