2008年2月28日木曜日

Swingで独自のボタンを作る

Swingでは、UI委譲でLook&Feelが統一されているので、独自のViewを持つ部品を作るのもどうかと思うが、いちおうできるようなのでやってみた。 ボタンといっても、いわゆるプッシュボタン以外も、ラジオボタンとかチェックボックスもボタンなので、クリックなどの操作で状態が変わるUI部品の類は、ボタンということになる。そういう意味では、独自の外観を持つボタンを作りたくなることもあるかもしれない。

Swingには、ボタンの機能が実装されている便利なクラス「AbstractButton」があるので、これを使う。AbstractButtonクラスのドキュメントを読めば、だいたいの作り方はわかるかもしれないが、とりあえず、最低限すべきであろうと思われる処理について書くことにする。

UIの描画はもちろん自前でするわけだが、AbstractButtonクラスを使うとしても、マウスなどの入力処理も書かなくてはならない。プッシュボタンの場合、マウスが押されたときに概観が変わるので当然といえばそうなのだが…

描画の処理
「protected void paintBorder(Graphics g);」を記述する。理由は定かではないが、printComponentなどを使わずにこのメソッドを書く。ボタンの状態によって描画する処理になる。
マウスイベントを拾う処理
MouseListenerインターフェースを実装して、コンストラクタでaddMouseListener(this);を呼び出す。
クリックされたときの処理
public void mouseClicked(MouseEvent e);に処理を書く。マウスボタンの切り分けは、MouseEventのgetButton();で「MouseEvent.BUTTONx」か、getModifiersEx();で「MouseEvent.BUTTONx_DOWN_MASK」で(xは1とか2)判断する。左クリックのときは、BUTTON1でいいのだが、右クリックの場合、マウスボタン数を意識する必要があるかもしれない。 UIの変更があるのであれば、内部的な状態の変更を保持して、repaint();を呼び出して再描画させる。ただし、場合によってはgetGraphics();でGraphicsを取得して、直接描画する必要もあるかもしれない。
ボタン押下の処理
もし、ボタンが押された状態でUIが変化するのであれば、public void mousePressed(MouseEvent e);とpublic void mouseReleased(MouseEvent e);を記述する。場合によっては、public void mouseEntered(MouseEvent e);とpublic void mouseExited(MouseEvent e);も記述する必要があるかもしれない。
キーイベントの処理
ここはでは実装してません(すみません)。たぶん、キー入力をしようとすると、フォーカスを意識しなくてはならないはずなので、処理はちょっと面倒かもしれない。いずれ、フォーカスのねたもわかり次第、どこかで記事を書くかもしれない。

あんまり、意味がないかもしれないが、ここまでのコードは以下のとおりになる。

public class MyButton extends AbstractButton implements MouseListener {
 public MyButton() {
  initialize();
 }
 private void initialize() {
  addMouseListener(this);
 }
 protected void paintBorder(Graphics g) {
  //状態に応じた描画をする
 }
 public void mouseClicked(MouseEvent e) {
  //マウスがクリックされたときの処理
 }
 public void mouseEntered(MouseEvent e) {
  //場合によっては何かをする
 }
 public void mouseExited(MouseEvent e) {
  //場合によっては何かをする
 }
 public void mousePressed(MouseEvent e) {
  //押されたときにUIが変化する場合
 }
 public void mouseReleased(MouseEvent e) {
  //押されたときにUIが変化する場合
 }
}

0 件のコメント: