Reputation: 11
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
public class HintTextField extends JTextField implements FocusListener
{
private String hint;
public HintTextField ()
{
this("");
}
public HintTextField(final String hint)
{
setHint(hint);
super.addFocusListener(this);
}
public void setHint(String hint)
{
this.hint = hint;
setUI(new HintTextFieldUI(hint, true));
//setText(this.hint);
}
public void focusGained(FocusEvent e)
{
if(this.getText().length() == 0)
{
super.setText("");
}
}
public void focusLost(FocusEvent e)
{
if(this.getText().length() == 0)
{
setHint(hint);
}
}
public String getText()
{
String typed = super.getText();
return typed.equals(hint)?"":typed;
}
}
class HintTextFieldUI extends javax.swing.plaf.basic.BasicTextFieldUI implements FocusListener
{
private String hint;
private boolean hideOnFocus;
private Color color;
public Color getColor()
{
return color;
}
public void setColor(Color color)
{
this.color = color;
repaint();
}
private void repaint()
{
if(getComponent() != null)
{
getComponent().repaint();
}
}
public boolean isHideOnFocus()
{
return hideOnFocus;
}
public void setHideOnFocus(boolean hideOnFocus)
{
this.hideOnFocus = hideOnFocus;
repaint();
}
public String getHint()
{
return hint;
}
public void setHint(String hint)
{
this.hint = hint;
repaint();
}
public HintTextFieldUI(String hint)
{
this(hint, false);
}
public HintTextFieldUI(String hint, boolean hideOnFocus)
{
this(hint, hideOnFocus, null);
}
public HintTextFieldUI(String hint, boolean hideOnFocus, Color color)
{
this.hint = hint;
this.hideOnFocus = hideOnFocus;
this.color = color;
}
protected void paintSafely(Graphics g)
{
super.paintSafely(g);
JTextComponent comp = getComponent();
if(hint != null && comp.getText().length() == 0 && (!(hideOnFocus && comp.hasFocus())))
{
if(color != null)
{
g.setColor(color);
}
else
{
g.setColor(Color.gray);
}
int padding = (comp.getHeight() - comp.getFont().getSize()) / 2;
g.drawString(hint, 5, comp.getHeight() - padding - 1);
}
}
public void focusGained(FocusEvent e)
{
if(hideOnFocus) repaint();
}
public void focusLost(FocusEvent e)
{
if(hideOnFocus) repaint();
}
protected void installListeners()
{
super.installListeners();
getComponent().addFocusListener(this);
}
protected void uninstallListeners()
{
super.uninstallListeners();
getComponent().removeFocusListener(this);
}
}
This is my code (JTextField
with input hint). Can someone help me to improve my code?
1) When I click the textfield, I don't want the hint to disappear. I want the hint to disappear only when I type something in the textfield.
2) How to code JPasswordField
with input hint?
How to create JTextField and JPasswordField like Facebook mobile login page (round JTextField
/PasswordField
and stick together)?
Upvotes: 0
Views: 1588
Reputation: 14003
Instead of setting the text for JTextField, just paint the hint directly. See the paintComponent()
method in this example:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.Document;
public class PlaceholderTextField extends JTextField {
public static void main(final String[] args) {
final PlaceholderTextField tf = new PlaceholderTextField("");
tf.setColumns(20);
tf.setPlaceholder("All your base are belong to us!");
final Font f = tf.getFont();
tf.setFont(new Font(f.getName(), f.getStyle(), 30));
JOptionPane.showMessageDialog(null, tf);
}
private String placeholder;
public PlaceholderTextField() {
}
public PlaceholderTextField(
final Document pDoc,
final String pText,
final int pColumns)
{
super(pDoc, pText, pColumns);
}
public PlaceholderTextField(final int pColumns) {
super(pColumns);
}
public PlaceholderTextField(final String pText) {
super(pText);
}
public PlaceholderTextField(final String pText, final int pColumns) {
super(pText, pColumns);
}
public String getPlaceholder() {
return placeholder;
}
@Override
protected void paintComponent(final Graphics pG) {
super.paintComponent(pG);
if (placeholder.length() == 0 || getText().length() > 0) {
return;
}
final Graphics2D g = (Graphics2D) pG;
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(getDisabledTextColor());
g.drawString(placeholder, getInsets().left, pG.getFontMetrics()
.getMaxAscent() + getInsets().top);
}
public void setPlaceholder(final String s) {
placeholder = s;
}
}
Upvotes: 0
Reputation: 324147
When I click the textfield, I don't want the hint to disappear. I want the hint to disappear only when I type something in the textfield.
Text Prompt provides this functionality.
I haven't tried it with a JPasswordField before, but it should work there as well.
Upvotes: 2
Reputation: 3
In order to disapear your hint when you type in text feild you should implement Keylistener. And in its keyPressed implementation you can write.
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(hideOnFocus) repaint();
}
Also comment out focusGained() implementation.
Upvotes: 0
Reputation: 13890
public class Hints
{
public static void main (String [] args)
{
Box mainPanel = Box.createVerticalBox ();
mainPanel.setBackground (Color.LIGHT_GRAY);
mainPanel.setOpaque (true);
mainPanel.add (new HintedTextField (12, "Login"));
mainPanel.add (Box.createVerticalStrut (1));
mainPanel.add (new HintedPasswordField (12, "Password"));
JPanel panel = new JPanel (new BorderLayout ());
panel.add (mainPanel, BorderLayout.CENTER);
panel.setBorder (BorderFactory.createEmptyBorder (8, 8, 8, 8));
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane ().setLayout (new BorderLayout ());
frame.getContentPane ().add (panel, BorderLayout.CENTER);
frame.pack ();
frame.setVisible (true);
}
private static class RoundedRectableBorder implements Border
{
private final boolean top;
private final boolean bottom;
public RoundedRectableBorder (boolean top, boolean bottom)
{
this.top = top;
this.bottom = bottom;
}
@Override
public void paintBorder (Component c, Graphics g, int x, int y,
int width, int height)
{
Area clipArea = new Area (new Rectangle (x, y, width, height));
clipArea.subtract (
new Area (
new Rectangle (
x + 5, top ? y + 5 : y, width - 10, height - (top ? 5 : 0) - (bottom ? 5 : 0))));
g.setClip (clipArea);
g.setColor (c.getParent ().getParent ().getBackground ());
g.fillRect (x, y, width, height);
g.setColor (c.getBackground ());
g.fillRoundRect (x, top ? y : (y - 5), width - 1, height + (top ? 5 : 0) + (bottom ? 5 : 0) - 1, 10, 10);
g.setColor (c.getParent ().getBackground ());
g.drawRoundRect (x, top ? y : (y - 5), width - 1, height + (top ? 5 : 0) + (bottom ? 5 : 0) - 1, 10, 10);
}
@Override
public Insets getBorderInsets (Component c)
{
return new Insets (5, 5, 5, 5);
}
@Override
public boolean isBorderOpaque ()
{
return false;
}
}
private static class HintedTextField extends JTextField
{
private final JTextField hintField;
public HintedTextField (int columns, String hint)
{
super (columns);
setBorder (new RoundedRectableBorder (true, false));
hintField = new JTextField (hint);
hintField.setBorder (BorderFactory.createEmptyBorder (5, 5, 5, 5));
}
@Override
protected void paintComponent (Graphics g)
{
super.paintComponent (g);
if (getText ().isEmpty ())
{
hintField.setBounds (getBounds ());
hintField.setForeground (getDisabledTextColor());
hintField.setOpaque (false);
hintField.paint (g);
}
}
}
private static class HintedPasswordField extends JPasswordField
{
private final JTextField hintField;
public HintedPasswordField (int columns, String hint)
{
super (columns);
setBorder (new RoundedRectableBorder (false, true));
hintField = new JTextField (hint);
hintField.setBorder (BorderFactory.createEmptyBorder (5, 5, 5, 5));
}
@Override
protected void paintComponent (Graphics g)
{
super.paintComponent (g);
if (getPassword ().length == 0)
{
hintField.setBounds (getBounds ());
hintField.setForeground (getDisabledTextColor());
hintField.setOpaque (false);
hintField.paint (g);
}
}
}
}
Upvotes: 1
Reputation: 79
i'm not a swing fan but i think that your first problem is in this method:
public void focusGained(FocusEvent e)
{
if(this.getText().length() == 0)
{
super.setText("");
}
}
to do that you say you have to create a thread that controls the text contained in the text field:
new Thread(){
public void run(){
while(true){
String s = this.getText();
if(s.length == 0 || s.equals(hint))
super.setText(hint);
else //significa che è cambiato il testo
if(s.contains(hint))
super.setText(s.replace(hint, ""));
}
}
}.start();
Upvotes: 0