イベント処理
何かと厄介なイベント処理ですが、うまく付き合えば強力な味方となります。
class LifeGamePanel(JPanel):
def this_mouseClicked(self, e):
life = self.detectLife(e)
print ">>>", life
life.reverse();
self.repaint();
メソッドthis_mouseClickedは、マウスでクリックした生命体を描画します。detectLifeを利用してイベントが発生した生命体lifeを特定し、隣接する生命体の数によってその表示を変化(反転)させます。反転reverseしたときには、repaintを利用してパネルを再描画します。
class LifeGamePanel(JPanel):
def paintComponent(self, g):
self.decideEdge();
self.paintItems(g)
def decideEdge(self):
Life.Edge = min(self.width, self.height) / self.dim
def paintItems(self, g):
for e in self.items:
e.paint(g)
repaintを呼び出すと、Swingのフレームワークに準拠してpaintComponentが呼び出されます。そのため、任意のコンポーネントを再描画したいときには、このメソッドを再定義しておきます。実際の処理はpaintItemsに委ね、パネルに配置したすべての生命体を再描画paintします。
メソッドdecideEdgeは、ウィンドウの大きさが変化したときに、再描画する生命体の大きさを決定します。ただし、属性値Life.Edgeを直接アクセスしているので、後の仕様変更でこれが問題となる可能性を否定できません。この問題を回避する方法は、後の連載で紹介します。
class LifeGamePanel(JPanel):
def detect(self, x, y):
obj = self.nullObject()
for e in self.items:
if e.detect(x, y): obj = e; break
return obj
def nullObject(self):
return Null
class Life(Shape):
def detect(self, x, y):
return (self.x, self.y) == (x, y)
メソッドdetectは、指定した座標x/yを持つ生命体を特定します。ただし、実際の処理は、各Lifeインスタンスeに委ね、その条件を満たす生命体objをリターン値とします。クラスLifeでは、指定した座標x/yと比較して、自分selfがその条件を満たすかどうかを判定した結果をリターン値とします。
