Ok, to be clear, I know how to extend the JTextField to hold a hint that disappears when the user places the cursor in the box.
I want to further extend (or edit) this. At first, the hint appears in a dark gray color. When the user places the cursor in the box, the hint stays there, but gets a light gray color. If the user types in anything, the hint goes away, and the text becomes black. If the user clears their input, the hint comes back with the same light gray color. If the user removes the cursor from the field, the text remains the same, and the color remains the same as before, except if the field is now empty (except for the hint), which causes the color to become dark gray.
The problem here is twofold: 1- I'm new to Java and UI applications, and I couldn't find a listener that is activated when the user inputs text (InputMethodListener doesn't work the way I want, or I couldn't figure out how to properly use it). 2- I don't want the hint to be selectable. Let's say the hint is "Hint", then if the user comes to select the box, and presses the mouse between the 'i' and 'n', then the cursor should appear before the 'H' anyway.
Here's the interface:
public HintTextField extends JTextField implements FocusListener {
public HintTextField(String hint) {}
@Override
public void focusGained(FocusEvent e) {} //change color
@Override
public void focusLost(FocusEvent e) {} //change color to darker gray if only hint left in text field
public void textGained() {} //remove hint, only display text, change color to black. if all text removed, show hint, change color to light gray
}
For detecting when the user types into the field, you want textField.getDocument().addDocumentListener
.
The only way I can think of to display text that cannot be selected in an enabled text component is to paint it directly:
private String hintText = "Hint";
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (getDocument().getLength() == 0) {
Rectangle viewBounds = new Rectangle();
SwingUtilities.calculateInnerArea(this, viewBounds);
Insets margin = getMargin();
viewBounds.x += margin.left;
viewBounds.y += margin.top;
viewBounds.width -= (margin.left + margin.right);
viewBounds.height -= (margin.top + margin.bottom);
Rectangle iconBounds = new Rectangle();
Rectangle textBounds = new Rectangle();
SwingUtilities.layoutCompoundLabel(this,
g.getFontMetrics(), hintText, null,
CENTER, getHorizontalAlignment(), CENTER, LEADING,
viewBounds, iconBounds, textBounds, 0);
// paintComponent must leave its Graphics argument unchanged.
Color originalColor = g.getColor();
g.setColor(Color.LIGHT_GRAY);
g.drawString(hintText,
textBounds.x, getBaseline(getWidth(), getHeight()));
g.setColor(originalColor);
}
}