How to display faint gray “ghost text” in a JTextField?

后端 未结 2 384
长发绾君心
长发绾君心 2020-12-01 12:39

I don\'t know if I got the right name for it, but I\'m looking to see if there is a specific way to implement a text field so that while it doesn\'t have focus and is empty,

2条回答
  •  执念已碎
    2020-12-01 12:58

    Thank you very much Guillaume, this is very good!

    I just changed a few things for ease of use:

    1. used JTextComponent instead of JTextField so it works with all text inputs
    2. took out the test class and made it public and non-static to make it stand-alone

    Here is the code:

    import java.awt.Color;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.text.JTextComponent;
    
    public class GhostText implements FocusListener, DocumentListener, PropertyChangeListener
    {
        private final JTextComponent textComp;
        private boolean isEmpty;
        private Color ghostColor;
        private Color foregroundColor;
        private final String ghostText;
    
        public GhostText(final JTextComponent textComp, String ghostText)
        {
            super();
            this.textComp = textComp;
            this.ghostText = ghostText;
            this.ghostColor = Color.LIGHT_GRAY;
            textComp.addFocusListener(this);
            registerListeners();
            updateState();
            if (!this.textComp.hasFocus())
            {
                focusLost(null);
            }
        }
    
        public void delete()
        {
            unregisterListeners();
            textComp.removeFocusListener(this);
        }
    
        private void registerListeners()
        {
            textComp.getDocument().addDocumentListener(this);
            textComp.addPropertyChangeListener("foreground", this);
        }
    
        private void unregisterListeners()
        {
            textComp.getDocument().removeDocumentListener(this);
            textComp.removePropertyChangeListener("foreground", this);
        }
    
        public Color getGhostColor()
        {
            return ghostColor;
        }
    
        public void setGhostColor(Color ghostColor)
        {
            this.ghostColor = ghostColor;
        }
    
        private void updateState()
        {
            isEmpty = textComp.getText().length() == 0;
            foregroundColor = textComp.getForeground();
        }
    
        @Override
        public void focusGained(FocusEvent e)
        {
            if (isEmpty)
            {
                unregisterListeners();
                try
                {
                    textComp.setText("");
                    textComp.setForeground(foregroundColor);
                }
                finally
                {
                    registerListeners();
                }
            }
    
        }
    
        @Override
        public void focusLost(FocusEvent e)
        {
            if (isEmpty)
            {
                unregisterListeners();
                try
                {
                    textComp.setText(ghostText);
                    textComp.setForeground(ghostColor);
                }
                finally
                {
                    registerListeners();
                }
            }
        }
    
        @Override
        public void propertyChange(PropertyChangeEvent evt)
        {
            updateState();
        }
    
        @Override
        public void changedUpdate(DocumentEvent e)
        {
            updateState();
        }
    
        @Override
        public void insertUpdate(DocumentEvent e)
        {
            updateState();
        }
    
        @Override
        public void removeUpdate(DocumentEvent e)
        {
            updateState();
        }
    
    }
    

提交回复
热议问题