例題で学ぶデザインパターン #7: テキストによるツリー表示

前の記事記事一覧次の記事

例題で学ぶ Jython/Swing デザインパターン《Jython2.5》
テキストによるツリー表示

《著》越智ことり+小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第1版♪2003/05/23 ● 第2版♪2009/04/03

■ 概要

例題により、アプリケーションを作成する過程を通して、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
            ])

GoFIterator パターンの効能によって、内包を使って表現するときには、モデル 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

》作業中です《

Last updated♪09/06/09