Wednesday, March 18, 2009 / Java

ヒント情報付きテキストフィールド (Java,Swing)

入力フォームに何を入力したらいいか例を示したい場合があります。 フォームの横に例を書く、という単純な方法もありますが、 以下のようにテキストフィールド上にヒントを書くという方法もあります。

textfield-1

もちろん、実際に入力するためにテキストフィールドに フォーカスを持って行ったときには、このヒントは消えます。

textfield-2

このようにすれば、ヒントを表示するスペースを節約できるだけでなく、 わかりやすくすることができます。

HintTextField.java

ヒント情報付きのテキストフィールドを実現するために、 JTextFieldを拡張しています。

拡張したポイントは、 paintComponent()メソッドをオーバーライドした上で…

  1. フォーカスが無いときには、ヒント情報を描画する
  2. テキストフィールドにテキストがセットされている場合は、ヒント情報は描画しない
  3. setHint(String)メソッドでヒント情報を設定

という具合です。

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JTextField;

public class HintTextField extends JTextField{
	private String hint;
	public void setHint(String hint){
		this.hint=hint;
	}

	public String getHint(){
		if(hint==null)
			hint="";
		return hint;
	}

	public void setText(String arg0) {
		super.setText(arg0);
		repaint();
	}
	
	public HintTextField(){
		super();
		
		addFocusListener(new FocusListener(){
			public void focusGained(FocusEvent arg0) {
				repaint();
			}
			public void focusLost(FocusEvent arg0) {
				repaint();
			}
		});
	}
	
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		if( hasFocus() ){
			return ;
		}
		if( getText().length()>0 ){
			return ;
		}
		if( getHint().length()<1){
			return ;
		}
		
		Font oldFont = g.getFont();
		Color oldColor = g.getColor();

		g.setFont(getFont());
		g.setColor(Color.LIGHT_GRAY);

		Insets insets = getBorder().getBorderInsets(this);
		int h = g.getFontMetrics().getAscent();
		g.drawString(getHint(),insets.left,insets.top+h);

		g.setFont(oldFont);
		g.setColor(oldColor);
	}
}

HintTextFieldのテスト用コード

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JFrame{
	public Test(){
		super();

		JButton okButton=new JButton(" OK ");
		okButton.requestFocus();

		HintTextField tf1=new HintTextField();
		tf1.setHint("(例)メロンパン");

		HintTextField tf2=new HintTextField();
		tf2.setHint("(例)お寿司");

		HintTextField tf3=new HintTextField();
		tf3.setHint("(例)カレーライス");

		Box box=Box.createVerticalBox();
		box.add(new JLabel("好きな食べ物を3つ書いてください。"));
		box.add(tf1);
		box.add(tf2);
		box.add(tf3);
		box.add(okButton);

		getContentPane().add(box,BorderLayout.NORTH);
	}

	public static void main(String[] args){
		Test t=new Test();
		t.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		t.pack();
		t.setVisible(true);
	}
}