2012-05-08 5 views
16

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?

+0

AF AIK, no. Ma sarei lieto di dirti diversamente –

+0

Posso dirti che Swing non lo fornisce in modo nativo (ma qualcuno potrebbe aver scritto una libreria di terze parti per farlo). –

+2

Questo potrebbe aiutare: http://stackoverflow.com/questions/1738966/java-jtextfield-with-input-hint – Ranga

risposta

36

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

* "Non sto cercando voti" * Duro. +1 Succhialo. ;) –

+1

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

8

Grazie mille Guillaume, questo è molto buono!

Ho appena cambiato un paio di cose per la facilità d'uso:

  1. utilizzato JTextComponent invece di JTextField in modo che funziona con tutti i testi ingressi
  2. 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(); 
    } 

} 
+0

come controllare vuoto jTextField programmaticamente? il metodo getText restituisce GhostText: | – do01

+0

Bello, ed è ancora meglio se, nel focusLost, si aggiunga questo: else { unregisterListeners(); prova { textComp.setForeground (foregroundColor); } infine { registerListeners(); } } –

Problemi correlati