2012-05-08 14 views
16

Nie wiem, czy mam odpowiednią nazwę, ale chcę sprawdzić, czy istnieje konkretny sposób zaimplementowania pola tekstowego, tak aby podczas gdy nie miał fokusa i był pusty, słabo szary ciąg tekstowy jest wyświetlany w polu. Kiedy pole zostanie kliknięte, tekst powinien zniknąć, dokładnie tak, jak działa pasek wyszukiwania podobny do paska StackOverflow. Wiem, że mogę zmienić użycie setForeground() i skupić słuchaczy, aby to osiągnąć, ale zastanawiałem się, czy ktoś wiedział o jakiejś implementacji Javy, która mogłaby sobie z tym poradzić.Jak wyświetlić słaby "tekst widmowy" w JTextField?

+0

AF AIK, nie. Ale byłbym zadowolony, gdyby ktoś mi o tym powiedział: –

+0

Mogę ci powiedzieć, że Swing nie zapewnia tego natywnie (ale ktoś mógł napisać bibliotekę innej firmy, aby to zrobić). –

+2

Może to pomóc: http://stackoverflow.com/questions/1738966/java-jtextfield-with-input-hint – Ranga

Odpowiedz

36

Za to, co jest warte, stwierdziłem, że jest to interesujące z punktu widzenia jego realizacji, więc postanowiłem podzielić się z Wami (nie szukam głosów).

To naprawdę nieinwazyjne, ponieważ wszystko, co musisz zrobić, to zadzwonić pod numer new GhostText(textField, "Please enter some text here...");. Reszta kodu służy tylko do uruchomienia.

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

* "Nie szukam głosów" * Trudne. +1 Ssać to. ;) –

+1

Może to być trochę wybredne, ale czy możesz to zrobić bez usuwania tekstu ducha, dopóki nie zostanie wpisana znak? Firefox może pokazać, o czym mówię: jeśli otworzysz nową kartę, pasek adresu zawiera tekst z napisem "Wyszukaj lub wpisz adres", który nie zniknie po ustawieniu pola, ale pozostanie, dopóki nie wpiszesz pierwszy znak. – ryvantage

8

Dziękuję bardzo Guillaume, to jest bardzo dobre!

Właśnie zmienił kilka rzeczy na łatwość obsługi:

  1. używane JTextComponent zamiast JTextField więc działa ze wszystkimi tekstu wejść
  2. wyjął klasę testową i sprawiał, że publiczne i non-static aby to stand-alone

Oto kod:

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

w jaki sposób programować program jTextField pusty? Metoda getText zwraca GhostText: | – do01

+0

Przyjemnie, i jest jeszcze lepiej, jeśli w focusLost, dodajesz to: else { unregisterListeners(); spróbuj { textComp.setForeground (foregroundColor); } wreszcie { registerListeners(); } } –

Powiązane problemy