Как отображать слабый серый «текст-призрак» в JTextField?
Я не знаю, получил ли я правильное имя для него, но я смотрю, есть ли какой-либо конкретный способ реализации текстового поля, так что, хотя он не имеет фокуса и пуст, слабая серая строка текст отображается в поле. Когда нажимается поле, текст должен уходить, точно так же, как работает панель поиска, похожая на панель StackOverflow. Я знаю, что я могу изменить использование setForeground()
и прослушивателей фокуса, чтобы достичь этого, но мне было просто интересно, знает ли кто-нибудь о какой-либо реализации Java, которая могла бы справиться с этим для меня.
- Динамические JComboBoxes
- добавление индикатора выполнения для каждой ячейки таблицы для прогресса файла - Java
- Перетаскивание пользовательского объекта из JList в JLabel
- SwingWorker не обновляет JProgressBar без Thread.sleep () в пользовательской диалоговой панели
- Как получить изображение из папки проекта?
- JAR Bundler с использованием OSXAdapter, заставляющий приложение запаздывать или заканчиваться
- Загрузка ресурсов с помощью getClass (). GetResource ()
- Почему заголовок JTable не отображается на изображении?
Для чего это стоит, мне было интересно реализовать его, поэтому я решил поделиться им с вами (я не ищу голоса).
Это действительно неинвазивно, так как все, что вам нужно сделать, это вызвать 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(); } }
Большое спасибо Гийому, это очень хорошо!
Я просто изменил несколько вещей для удобства использования:
- использовал JTextComponent вместо JTextField, чтобы он работал со всеми текстовыми вводами
- вынул тестовый class и сделал его общедоступным и нестационарным, чтобы сделать его автономным
Вот код:
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(); } }