web-dev-qa-db-ja.com

Java入力ヒント付きのJTextField

javax.swing.JTextFieldにヒント値を追加したいと思います。 <input type="text" title="bla">のFirefoxレンダリングのように見えるはずです。これにより、背景にテキスト「bla」を含む編集フィールドが作成されます。テキストボックスにフォーカスがある場合、タイトルテキストは消え、ユーザーがテキストなしで編集ボックスを離れると、再び表示されます。

このようなことをする(無料の)Swingコンポーネントはありますか?

42
Wienczny

これを見てください: http://code.google.com/p/xswingx/

ところで、自分で実装することはそれほど難しくありません。いくつかのリスナーとカスタムレンダラーと出来上がり。

15
Dmitry

独自に作成できます:

_import Java.awt.*;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import Java.awt.event.FocusEvent;
import Java.awt.event.FocusListener;
import javax.swing.*;

public class Main {

  public static void main(String[] args) {

    final JFrame frame = new JFrame();

    frame.setLayout(new BorderLayout());

    final JTextField textFieldA = new HintTextField("A hint here");
    final JTextField textFieldB = new HintTextField("Another hint here");

    frame.add(textFieldA, BorderLayout.NORTH);
    frame.add(textFieldB, BorderLayout.CENTER);
    JButton btnGetText = new JButton("Get text");

    btnGetText.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        String message = String.format("textFieldA='%s', textFieldB='%s'",
            textFieldA.getText(), textFieldB.getText());
        JOptionPane.showMessageDialog(frame, message);
      }
    });

    frame.add(btnGetText, BorderLayout.SOUTH);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.pack();
  }
}

class HintTextField extends JTextField implements FocusListener {

  private final String hint;
  private boolean showingHint;

  public HintTextField(final String hint) {
    super(hint);
    this.hint = hint;
    this.showingHint = true;
    super.addFocusListener(this);
  }

  @Override
  public void focusGained(FocusEvent e) {
    if(this.getText().isEmpty()) {
      super.setText("");
      showingHint = false;
    }
  }
  @Override
  public void focusLost(FocusEvent e) {
    if(this.getText().isEmpty()) {
      super.setText(hint);
      showingHint = true;
    }
  }

  @Override
  public String getText() {
    return showingHint ? "" : super.getText();
  }
}
_

まだJava 1.5)を使用している場合は、this.getText().isEmpty()this.getText().length() == 0に置き換えます。

53
Bart Kiers

単一クラスのコピー/貼り付けソリューションを次に示します。

_import Java.awt.Color;
import Java.awt.Graphics;
import Java.awt.event.FocusEvent;
import Java.awt.event.FocusListener;

import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.JTextComponent;


public class HintTextFieldUI extends 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;
    }

    @Override
    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(comp.getForeground().brighter().brighter().brighter());              
            }
            int padding = (comp.getHeight() - comp.getFont().getSize())/2;
            g.drawString(hint, 2, comp.getHeight()-padding-1);          
        }
    }

    @Override
    public void focusGained(FocusEvent e) {
        if(hideOnFocus) repaint();

    }

    @Override
    public void focusLost(FocusEvent e) {
        if(hideOnFocus) repaint();
    }
    @Override
    protected void installListeners() {
        super.installListeners();
        getComponent().addFocusListener(this);
    }
    @Override
    protected void uninstallListeners() {
        super.uninstallListeners();
        getComponent().removeFocusListener(this);
    }
}
_

次のように使用します。

_TextField field = new JTextField();
field.setUI(new HintTextFieldUI("Search", true));
_

protected void paintSafely(Graphics g)で発生していることに注意してください。

15
culmat

以下は、どのL&Fでも見栄えの良い簡単な方法です。

public class HintTextField extends JTextField {
    public HintTextField(String hint) {
        _hint = hint;
    }
    @Override
    public void Paint(Graphics g) {
        super.Paint(g);
        if (getText().length() == 0) {
            int h = getHeight();
            ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            Insets ins = getInsets();
            FontMetrics fm = g.getFontMetrics();
            int c0 = getBackground().getRGB();
            int c1 = getForeground().getRGB();
            int m = 0xfefefefe;
            int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1);
            g.setColor(new Color(c2, true));
            g.drawString(_hint, ins.left, h / 2 + fm.getAscent() / 2 - 2);
        }
    }
    private final String _hint;
}
13
Adam Gawne-Cain

https://github.com/mgarin/weblaf/ でWebLookAndFeelをご覧ください

WebTextField txtName = new com.alee.laf.text.WebTextField();

txtName.setHideInputPromptOnFocus(false);

txtName.setInputPrompt("Name");

txtName.setInputPromptFont(new Java.awt.Font("Ubuntu", 0, 18));

txtName.setInputPromptForeground(new Java.awt.Color(102, 102, 102));

txtName.setInputPromptPosition(0);
3
user2473015

Swingコンポーネント(つまり、JComponentを拡張するもの)については、setToolTipText(String)メソッドを呼び出すことができます。

詳細については、次のリンクを参照してください。

3
Matt

それでも解決策を探している場合は、参照用に他の回答(Bart Kiersとculmat)を組み合わせたものがあります。

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



Usage:
HintTextField field = new HintTextField();
field.setHint("Here's a hint");
2
user814168

これは、フォーカスリスナーを使用してテキストフィールドのコンテンツを更新することで実現できます。

クラスにフォーカスリスナーインターフェイスを実装します。

class YourClass implements FocusListener

フィールドを空白にするフォーカスが取得されたときにキャッチするメソッドを追加します。

public void focusGained(FocusEvent e) {
    if(JTextField1.getText().equals("Username")) {
        JTextField1.setText("");
    }
}

フィールドが空白の場合、デフォルトのエントリを再表示するためにフォーカスが失われたときにキャッチするメソッドを追加します。

public void focusLost(FocusEvent e) {
    if(JTextField1.getText().equals("")) {
        JTextField1.setText("Username");
        // you should prevent the form from being processed in this state
        // as it will literally contain "Username" for the username
    }
}

クラスをテキストフィールドのフォーカスリスナーとして登録します。

textField.addFocusListener(this);

詳細については、「Javaチュートリアル」の フォーカスリスナーの作成方法 を参照してください。

0
Shivam Rajput