Java - 关于JTextField和JPasswordField的问题

时间:2013-02-17 13:40:11

标签: java swing jtextfield jpasswordfield

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);
    }
}

这是我的代码(带有输入提示的JTextField)。有人可以帮助我改进我的代码吗?

1)当我点击文本字段时,我不希望提示消失。我希望只有当我在文本字段中输入内容时,提示才会消失。

2)如何使用输入提示对JPasswordField进行编码?

如何像Facebook移动登录页面一样创建JTextField和JPasswordField(围绕JTextField / PasswordField并粘在一起)?

5 个答案:

答案 0 :(得分:2)

  

当我点击文本字段时,我不希望提示消失。我希望只有当我在文本字段中输入内容时,提示才会消失。

Text Prompt提供此功能。

我之前没有尝试使用JPasswordField,但它也应该在那里工作。

答案 1 :(得分:1)

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);
            }
        }
    }
}

答案 2 :(得分:0)

我不是摇摆迷,但我认为你的第一个问题是这个方法:

public void focusGained(FocusEvent e)
{
    if(this.getText().length() == 0)
    {
        super.setText("");
    }
}

要做到这一点,你说你必须创建一个控制文本字段中包含的文本的线程:

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();

答案 3 :(得分:0)

为了在输入文本字段时消除你的提示,你应该实现Keylistener。在其keyPressed实现中,您可以编写。

@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    if(hideOnFocus) repaint();
}

同时注释掉focusGained()的实现。

答案 4 :(得分:0)

不是直接为JTextField设置文本,而是直接绘制提示。请参阅此示例中的paintComponent()方法:

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;
    }

}