例題で学ぶデザインパターン #7: テキストによるツリー表示
例題で学ぶ Jython/Swing デザインパターン《Jython2.5》
テキストによるツリー表示
■ 概要
例題により、アプリケーションを作成する過程を通して、Jython/Swing によるデザインパターンを習得します。
この課題では、Swing/GUI を使って階層構造を持つ情報を提示します。〈GoF〉Composite/Iterator/Visitor/Command パターンを導入すると、if/for 文によるコードの汚染、配列の境界問題が解消されるので、要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できるようになります。
《Note》JPython1.1.x/Jython2.1.x 用に作成したセミナー課題を、Jython2.5 で再構成しました。
事例:モジュールを起動する
モジュールを起動すると、次のようなウィンドウが現れます。
$ jython2.5b3 -i step06/TreeEx.py ツリーの根 JTree の傘下にある、部分ツリーの全ノードを表示します 部分ツリー colors の傘下にあるノードを表示します。 ノード violet を表示します。
ツリー JTree を構成する各ノードを選択すると、テキスト領域 JTextArea には、その部分ツリーの傘下にある全ノードが表示されます。また、末端にあるノード violet を選択すると、テキスト領域には violet だけが表示されます。
事例:コードの解説
■ モジュール:TreeView.py
... from java.awt import Font class View(JPanel): def __init__(self, **keys): ... self.textArea = JTextArea( font = Font("Courier", Font.PLAIN, 12), )
テキスト形式でツリーを表示するために、フォント Font を指定します。各ノードのレベルをインデントで表現するのに適した、Courier を指定します。
■ モジュール:TreeComposite.py
class Node(object):
def __init__(self, node, level=0, *args, **keys):
self.node = node
self.level = level
新たなインスタンス属性 self.level は、各ノードのレベル(深さ)をインデントで表現するために必要です。
def __str__(self): return "\n".join([ "%s%s%s"%( "| "*(e.level-1), "+-- "*(not not e.level), e.node, ) for e in self ])
〈GoF〉Iterator パターンの効能によって、内包を使って表現するときには、モデル self を指定するだけで、各ノード e を順に参照できます。そこで、インデントを表わす文字列に続いて、各ノード e.node の名前を付加します。
def children(self):
return reduce(
lambda s, e: s + Node(e, self.level+1).children(),
self.node.children(),
[self])
コンストラクター Node の第2引数には、子ノードのレベル数を指定します。メソッド children は「再帰的な」階層構造に沿って呼び出されるので、値が1つずつ増えインデントが深くなります。
Tips
》作業中です《