propiedades eventos java swing jtextfield

java - eventos - ¿Cómo mostrar el débil "texto fantasma" gris en un JTextField?



jtextfield java 8 (2)

No sé si obtuve el nombre correcto para ello, pero estoy buscando para ver si hay una forma específica de implementar un campo de texto para que mientras no esté enfocado y esté vacío, aparezca una débil cadena gris de El texto se muestra en el campo. Cuando se hace clic en el campo, el texto debe desaparecer, exactamente como funciona la barra de búsqueda como la de StackOverflow. Sé que puedo cambiar el uso de setForeground() y enfocar a los oyentes para lograr esto, pero me preguntaba si alguien sabía de alguna implementación de Java que pudiera manejar esto por mí.


Muchas gracias Guillaume, esto es muy bueno!

Acabo de cambiar algunas cosas para facilitar su uso:

  1. usé JTextComponent en lugar de JTextField para que funcione con todas las entradas de texto
  2. sacó la clase de prueba y la hizo pública y no estática para hacerla independiente

Aquí está el código:

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(); } }


Por lo que vale la pena, me pareció interesante implementarlo, así que pensé en compartirlo con ustedes (no estoy buscando votos).

Es realmente no invasivo ya que todo lo que tienes que hacer es llamar a new GhostText(textField, "Please enter some text here..."); . El resto del código es solo para ejecutarlo.

import java.awt.Color; import java.awt.Dimension; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; public class Test { public static class GhostText implements FocusListener, DocumentListener, PropertyChangeListener { private final JTextField textfield; private boolean isEmpty; private Color ghostColor; private Color foregroundColor; private final String ghostText; protected GhostText(final JTextField textfield, String ghostText) { super(); this.textfield = textfield; this.ghostText = ghostText; this.ghostColor = Color.LIGHT_GRAY; textfield.addFocusListener(this); registerListeners(); updateState(); if (!this.textfield.hasFocus()) { focusLost(null); } } public void delete() { unregisterListeners(); textfield.removeFocusListener(this); } private void registerListeners() { textfield.getDocument().addDocumentListener(this); textfield.addPropertyChangeListener("foreground", this); } private void unregisterListeners() { textfield.getDocument().removeDocumentListener(this); textfield.removePropertyChangeListener("foreground", this); } public Color getGhostColor() { return ghostColor; } public void setGhostColor(Color ghostColor) { this.ghostColor = ghostColor; } private void updateState() { isEmpty = textfield.getText().length() == 0; foregroundColor = textfield.getForeground(); } @Override public void focusGained(FocusEvent e) { if (isEmpty) { unregisterListeners(); try { textfield.setText(""); textfield.setForeground(foregroundColor); } finally { registerListeners(); } } } @Override public void focusLost(FocusEvent e) { if (isEmpty) { unregisterListeners(); try { textfield.setText(ghostText); textfield.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(); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { init(); } }); } public static void init() { JFrame frame = new JFrame("Test ghost text"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); JTextField textField = new JTextField(); JButton button = new JButton("Grab focus"); GhostText ghostText = new GhostText(textField, "Please enter some text here..."); textField.setPreferredSize(new Dimension(300, 24)); panel.add(textField); panel.add(button); frame.add(panel); frame.pack(); frame.setVisible(true); button.grabFocus(); } }