例題で学ぶデザインパターン #1.2: Canvas を利用する

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

例題で学ぶ Jython/Swing デザインパターン《Jython2.5》
Canvas を利用する

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

■ 概要

アプリケーションを作成する過程を通して、Jython/Swing によるデザインパターンを習得します。

この課題では、Swing/GUI を使ってモデルの変化に呼応する複数のビューを提示します。〈GoF〉Observer パターンを導入すると、依存性を扱うのが容易になるので、要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できるようになります。

《Note》JPython1.1.x/Jython2.1.x 用に作成したセミナー課題を、Jython2.5 で再構成しました。

事例:モジュールを起動する

モジュールを起動すると、次のようなウィンドウが現れます。

$ jython2.5.0 -i step02/ListEx.py 

 

(左)リスト JList を構成する各項目を選択すると、(右)キャンバス Canvas の背景色が変化します。たとえば、ノード aqua を選択すると、キャンバスの背景が水色になります。

事例:Java の世界を Jython から観察する

実行中の Java アプリケーションの状態を、Jython の対話モードで確認できるので便利です。リストを選択したのと同じ動作は、次のコードでも表現できます。

>>> view = Xview
>>> type(view)
<type 'javax.swing.JList'>
>>> print view.selectedValue
None
>>> view.selectedIndex = 2
>>> print view.selectedValue
aqua

大域変数 Xview を介して、JList を参照できます。すると、なにも選択していない状態では、None が得られます。そこで、先頭からのオフセット位置 2 にある項目を選択すると、その値が aqua に変化したのが分かります。

《Note》selectedIndex により、指定したオフセット位置にある(単一の)項目を選択します。

事例:コードの解説

■ モジュール:ListEx.py
...
from java.awt import Canvas
from javax.swing import JSplitPane

class View(JPanel):
    def __init__(self, *args, **keys):
        listData = [e for e in dir(colors) if not e.startswith("_")]
        list = JList(
            listData,
            valueChanged = self.valueChanged,
            )

JList の項目を選択すると(値が変更されたときに)メソッド valueChanged が呼び出されます。

        self.canvas = Canvas()

キャンバス Canvas の背景色を変化させます。

        pane = JSplitPane(
            JSplitPane.HORIZONTAL_SPLIT,
            leftComponent  = JScrollPane(list),
            rightComponent = self.canvas,
            )
        super(self.__class__,self).__init__(
            layout = BorderLayout(),
            )
        self.add(
            pane, BorderLayout.CENTER,
            )
    def valueChanged(self, e):
        value = e.source.selectedValue
        self.canvas.background = eval("colors.%s"%value)

ノードを選択した(値が変更された)ときに発生するイベント e から、選択した項目 node が得られます。

class Window(JFrame):
    def __init__(self, title, *args, **keys):
        super(self.__class__,self).__init__(
            title = title,
            contentPane = View(),
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
            )

Tips

》作業中です《

Last updated♪09/06/23