如何在JTextField中显示淡灰色的“鬼文本”?
2022-09-02 11:37:20
我不知道我是否得到了正确的名称,但我正在研究是否有一种特定的方法来实现文本字段,以便在它没有焦点并且是空的时,在字段中显示一个淡灰色的文本字符串。单击该字段时,文本应该会消失,就像 StackOverflow 中的搜索栏的工作方式一样。我知道我可以改变使用和集中听众来实现这一点,但我只是想知道是否有人知道一些Java实现可以为我处理这个问题。setForeground()
我不知道我是否得到了正确的名称,但我正在研究是否有一种特定的方法来实现文本字段,以便在它没有焦点并且是空的时,在字段中显示一个淡灰色的文本字符串。单击该字段时,文本应该会消失,就像 StackOverflow 中的搜索栏的工作方式一样。我知道我可以改变使用和集中听众来实现这一点,但我只是想知道是否有人知道一些Java实现可以为我处理这个问题。setForeground()
对于它的价值,我发现实际实现它很有趣,所以我想与你分享(我不是在寻找选票)。
这真的是非侵入性的,因为你所要做的就是打电话。代码的其余部分只是为了让它运行。new GhostText(textField, "Please enter some text here...");
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();
}
}
非常感谢纪尧姆,这非常好!
为了便于使用,我只是更改了一些内容:
代码如下:
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();
}
}