4.5 プロパティの変更
4.5.1 プロパティ変更リスナ
「$4.1 コンポーネントのプロパティ」では、コンポーネントには前景色や背景色などの値が設定または取得できることを説明しました。
Component クラスはフォント、前景色、背景色などのプロパティが変更されたことを通知してくれます。これは、従来のマウスイベントやキーボードイベントの処理と同じ方法で、プロパティ変更リスナを実装し、これをコンポーネントに登録するのです。プロパティ変更リスナを登録するには addPropertyChangeListener() メソッドを、登録されているプロパティ変更リスナを解除するにはremovePropertyChangeListener() メソッドを、現在登録されているプロパティ変更リスナを取得するには getPropertyChangeListeners() メソッドを使います。
public void addPropertyChangeListener(PropertyChangeListener listener)
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)
public void removePropertyChangeListener(PropertyChangeListener listener)
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener)
public PropertyChangeListener[] getPropertyChangeListeners()
public PropertyChangeListener[] getPropertyChangeListeners(String propertyName)
propertyName 引数を指定しない場合は全てのプロパティが対称になりますが、propertyName を指定するメソッドでは特定のプロパティに関連付けて操作が行われます。この場合は、指定した名前のプロパティにのみリスナが関連付けられるため、例えば "font" という名前でプロパティ変更リスナを追加すると、フォントの変更時のみイベントの通知が発生します。
これらの引数に指定するリスナは java.beans.PropertyChangeListener インタフェースです。java.awt.event パッケージではなく java.beans パッケージで提供されている JavaBeans アーキテクチャの一部であることに注意してください。JavaBeans はプロパティのテキスト表現方法などを提供し、コンポーネントの長期持続性を実現するためのパッケージですが、本書の範囲外なので詳細は省略します。コンポーネントが JavaBeans をサポートすれば統一された方法でコンポーネント同士が通信できるようになります。
PropertyChangeListener インタフェースが宣言するメソッドは propertyChange() のみです。
public void propertyChange(PropertyChangeEvent evt)
このメソッドは登録されているコンポーネントのプロパティが変更されたときに呼び出されます。evt パラメータには java.beans.PropertyChangeEvent クラスのオブジェクトが渡されます。
java.lang.Object | +--java.util.EventObject | +--java.beans.PropertyChangeEvent
public class PropertyChangeEvent extends EventObject
このクラスはプロパティ変更イベントの情報を提供します。変更されたプロパティの名前は getPropertyName() メソッド、元のプロパティの値は getOldValue() メソッド、そして新しい値は getNewValue() メソッドから取得することができます。
public Object getNewValue()
public Object getOldValue()
public String getPropertyName()
getPropertyName() メソッドから得られる文字列を調べれば、どのプロパティが変更されたのかを知ることができます。PropertyChangeEvent クラスも JavaBeans の一部なので、MouseEvent や KeyEvent クラスとは異なり AWTEvent クラスのサブクラスではないことに注意してください。
import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.beans.*; //<applet code="Test.class" width="400" height= "400"></applet> public class Test extends Applet implements PropertyChangeListener, MouseListener { private String name = "" , oldValue = "" , newValue = ""; //PropertyChangeListener の実装////////////// public void propertyChange(PropertyChangeEvent e) { name = "プロパティ名=" + e.getPropertyName(); oldValue = "古い値=" + e.getOldValue(); newValue = "新しい値=" + e.getNewValue(); } /////////////////////////////////////////// public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) { if (e.getButton() == e.BUTTON1) setBackground(Color.BLUE); else setForeground(Color.RED); repaint(); } public void mouseReleased(MouseEvent e) { if (e.getButton() == e.BUTTON1) setBackground(Color.WHITE); else setForeground(Color.BLACK); repaint(); } public void mouseEntered(MouseEvent e) { setFont(new Font("Serif" , Font.BOLD , 20)); repaint(); } public void mouseExited(MouseEvent e) { setFont(new Font("Serif" , Font.PLAIN , 15)); repaint(); } public void init() { addMouseListener(this); addPropertyChangeListener(this); } public void paint(Graphics g) { g.drawString(name , 0 , g.getFontMetrics().getAscent()); g.drawString(oldValue , 0 , g.getFontMetrics().getAscent() * 2); g.drawString(newValue , 0 , g.getFontMetrics().getAscent() * 3); } }
コード1は、プロパティ変更イベントが発生すると、変更されたプロパティの名前、プロパティが変更される前の元の値、変更後の新しい値をアプレットに表示します。このプログラムでは、マウスイベントが発生するとコンポーネントのプロパティを変更するように仕組んでいます。マウスカーソルがアプレット内に入ったり、出たりすればフォントが変更され、ボタンを押したり、離したりすると前景色や背景色が変更されます。
設計一般の解釈では位置やサイズなどもプロパティと解釈されますが、PropertyChangeListener に通知されるのは前景色や背景色、フォントなどの限られたものです。このように JavaBeans の PropertyChangeListener に変更があったことを報告するプロパティのことをバウンドプロパティと呼びます。