Non so se ho il nome giusto per questo, ma sto cercando di vedere se c'è un modo specifico per implementare un campo di testo in modo che mentre non ha il focus e sia vuoto, un grigio tenue una stringa di testo viene visualizzata nel campo. Quando si fa clic sul campo, il testo dovrebbe andare via, esattamente come funziona la barra di ricerca come quella di StackOverflow. So che posso cambiare l'uso di setForeground()
e focalizzare gli ascoltatori per raggiungere questo obiettivo, ma mi stavo chiedendo se qualcuno fosse a conoscenza di qualche implementazione Java in grado di gestirmi.Come visualizzare un "testo fantasma" grigio debole in un campo JTextField?
risposta
Per quello che vale, ho trovato interessante implementarlo effettivamente, quindi ho pensato di condividerlo con te (non sto cercando voti).
È davvero non invasivo in quanto tutto ciò che dovete fare è chiamare new GhostText(textField, "Please enter some text here...");
. Il resto del codice è solo per farlo funzionare.
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();
}
}
* "Non sto cercando voti" * Duro. +1 Succhialo. ;) –
Questo potrebbe essere un po 'pignolo, ma potresti farlo senza rimuovere il testo fantasma fino a quando non viene digitato un carattere? Firefox è in grado di mostrare di cosa sto parlando: se apri una nuova scheda, la barra degli indirizzi contiene il testo fantasma che dice "Cerca o inserisci indirizzo" che non scomparirà quando focalizzi il campo ma rimarrà fino a quando non digiti il primo personaggio. – ryvantage
Grazie mille Guillaume, questo è molto buono!
Ho appena cambiato un paio di cose per la facilità d'uso:
- utilizzato JTextComponent invece di JTextField in modo che funziona con tutti i testi ingressi
- tirò fuori la classe di test e ne ha fatto pubblico e non statico per renderlo autonomo
Ecco il codice:
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();
}
}
come controllare vuoto jTextField programmaticamente? il metodo getText restituisce GhostText: | – do01
Bello, ed è ancora meglio se, nel focusLost, si aggiunga questo: else { unregisterListeners(); prova { textComp.setForeground (foregroundColor); } infine { registerListeners(); } } –
AF AIK, no. Ma sarei lieto di dirti diversamente –
Posso dirti che Swing non lo fornisce in modo nativo (ma qualcuno potrebbe aver scritto una libreria di terze parti per farlo). –
Questo potrebbe aiutare: http://stackoverflow.com/questions/1738966/java-jtextfield-with-input-hint – Ranga