開発覚え書き

ソフトウェアシステムの開発に関わるさまざまなことの覚え書き

Java AWTコンポーネントでのイベント処理の簡単な流れ

2006-06-02 14:54:36 | Weblog
JavaのGUIプログラムで利用されているイベント処理の簡単な流れを整理してみた。Java 2 SDK 1.4.2 のソースを斜め読みした結果も含まれている。
ただし、以下はAWTコンポーネントの処理内容である。


Swingのコンポーネントでは違っているようだ。JComponent に

protected EventListenerList listenerList

があり、このリストの登録リスナを呼び出すようだ。
詳細がわかれば後日まとめたい。


細かい所は省き、単純化して説明してある。

(1)
JavaではGUI部品がある場合、イベントは EventDispatchThread というイ
ベント処理専用のスレッドが動いている。
その EventDispatchThread はイベントキューに溜まったイベントを順次取り出し、各コンポーネントの

java.awt.Component クラスの public final void dispatchEvent(AWTEvent e);

を呼び出す。

(2)
dispatchEvent() の実際の処理は

java.awt.Component クラスまたは java.awt.Container クラスなどの void dispatchEventImpl(AWTEvent e);


で行われる。
※ Container クラスの dispatchEventImpl() の細かい内容は分からないが、その中で処理できないものは結局 Component クラスの dispatchEventImpl() で処理される。

(3)
Component クラスの dispatchEventImpl() では、

イベントの ID を取り出し、その種類に合せた処理を行うが、
イベントが


protected final void enableEvents(long eventsToEnable);


あるいは、各イベント XXX の


public void addXXXListener(XXXListener l);


によって有効化されている場合、


protected void processEvent(AWTEvent e);


が呼び出され処理される。

(4)
processEvent() では、イベントの種類に応じてそれぞれ


protected void processComponentEvent(ComponentEvent e);
protected void processFocusEvent(FocusEvent e);
protected void processKeyEvent(KeyEvent e);
protected void processMouseEvent(MouseEvent e);
protected void processMouseMotionEvent(MouseEvent e);
protected void processMouseWheelEvent(MouseWheelEvent e);
protected void processInputMethodEvent(InputMethodEvent e);
protected void processHierarchyEvent(HierarchyEvent e);
protected void processHierarchyBoundsEvent(HierarchyEvent e);


などが呼び出される。

(5)
呼ばれた processKeyEvent() や processMouseEvent() 等では、イベントに対応したリスナの「イベントIDの細かい分類に従ったメソッド」が呼ばれ処理される。
例えば、ID が MouseEvent.MOUSE_PRESSED ならマウスリスナの


void mousePressed(MouseEvent e);


が呼び出され処理される。

(補足)
なお、上で出てきた Component の processEvent() メソッドおよび processXXXEvent() メソッドはすべて protected なので、
自前で細かい処理をしたい場合、サブクラスで processEvent() メソッドまたは processXXXEvent() をオーバーライドして処理を記述できる。
ただし、利用の際 enableEvents() を呼んで、処理したいイベントをそのコンポーネントで処理できるようしておく必要がある。
※ オーバーライドしたメソッド中では継承元の元のメソッド (super.processEvent() メソッドまたは super.processXXXEvent() メソッド) を呼ぶことが求められている。

JFrameのコンテントペインのサイズ設定 (2)

2006-06-01 08:57:02 | Weblog
Java で JFrame のコンテントペインのサイズ設定 (1)」で、表示状態に切り替え insets を求め、それを加えて setSize する方法を書いたが、あまりSwing的でなかった。

Swing的には

コンテントペインの preferredSize を希望サイズに設定しておき、
フレームで java.awt.Window クラスの public void pack(); を呼ぶことによりコンテントペインを推奨サイズに合せてもらう

のがよさそうだ。
フレームのコンストラクタなど初期化時に

    getContentPane().setPreferredSize(new Dimension(希望する幅, 希望する高さ));

としておき、

フレームを表示するときに、
    pack();
    setVisible(true);

のようにすればよい。これだと余分に表示状態・非表示状態を切り替える必要がない。