でたらめな言葉のLWUITTのUIコンポーネントコード構造を簡単に分析します.


回転:http://www.dongmian.org/2010/02/01/でたらめな言葉のlwuitのモジュールのコードの構造は簡単に分析します/
 
LWUITT:  https://lwuit.dev.java.net/ LWUITTはライト級JavaME UIツールです.主な特性としては、SwingのMVCアーキテクチャのように、様々なレイアウト(Layouts)、皮膚の交換、フォント、タッチスクリーン、アニメーション効果、Richコントロール、3 D集積、Painter、パターン対額縁、I 18 N/L 10 Nなどがあります.ちなみにLWUITTはsun社が主に押しているグラフィックライブラリで、wtk 3.0の中にはすでに内蔵されているライブラリです.
LWUITTのコンポーネントはすべてcomp.sun.lwuitというバッグの下にあります.すべてのコンポーネントはComponentというクラスを引き継ぎます.ここでComponentはcompsiteのデザインモデルを使用しています.
LWUITTのコンポーネント・システムをよりイメージするために理解する.以下のUIコンポーネントの関係図が見られます.
【図1】Componentの継承関係
図からわかるように、Componentは五つの種類に分けられています.
1、コンタイナー
2、Label
3、List
4、Media Component
5、TextArea
Continerは他の4つのコンポーネントとは違って、サブノードを格納することができ、そのコードは次の方法ができる.
Container         


void  addComponent (Object constraints, Component cmp)
void  addComponent (int index, Object constraints, Component cmp)
void  addComponent (int index, Component cmp)
void  replaceAndWait (final Component current, final Component next, final Transition t)
void  replace (final Component current, final Component next, final Transition t)
void  removeComponent (Component cmp)
void  flushReplace ()
void  removeAll ()
各コンポーネントのpaint方法は何をしていますか?
まずContinerという種類を見ますと、Continerの意味は容器で、そのpaint方法はそれに含まれているComponeごとにpaintInternalを調整する方法があります.コードは以下の通りです
 component paint   

    public void paint(Graphics g) {
        layoutContainer();
        g.translate(getX(), getY());
        int size = components.size();
        for (int i = 0; i < size; i++) {
            Component cmp = (Component)components.elementAt(i);
            cmp.paintInternal(g, false);
        }
        g.translate(-getX(), -getY());
    } 
paintInternal方法にはscrollbarとscrollbarがあります.コードは以下の通りです.
 component paintInternal   

     final void paintInternal(Graphics g, boolean paintIntersects) {
        if (!isVisible()) {
            return;
        }
        int oX = g.getClipX();
        int oY = g.getClipY();
        int oWidth = g.getClipWidth();
        int oHeight = g.getClipHeight();
        if (bounds.intersects(oX, oY, oWidth, oHeight)) {
            g.clipRect(getX(), getY(), getWidth(), getHeight());
            paintBackground(g);
            //    scrollbar
            if (isScrollable()) {
                int scrollX = getScrollX();
                int scrollY = getScrollY();
                g.translate(-scrollX, -scrollY);
                //  paint      

                  paint(g);
                g.translate(scrollX, scrollY);
                if (isScrollVisible) {
                    paintScrollbars(g);
                }
            } else {
                paint(g);
            }
            if (isBorderPainted()) {
                paintBorder(g);
            }

            //paint all the intersecting Components above the Component
            if (paintIntersects && parent != null) {
                paintIntersectingComponentsAbove(g);
            }

            g.setClip(oX, oY, oWidth, oHeight);
        }
    }
ここで注意すべきpaintの方法は、多状態性によって、各Componentの本当の方法を呼び出すことができます.
Continerの下のサブクラスはCompintのpaintメソッドを呼び出すが、Labelのサブクラスは、Spinner以外に、paint方法は次のような方法を呼び出す.
 Label   paint   

 UIManager.getInstance().getLookAndFeel().drawXXXX(g); 
この中のdrawXXXXは対応するコンポーネント名を表しています.例えば、CheckBoxというのは、その呼び方です.
 CheckBox paint  

 UIManager.getInstance().getLookAndFeel().drawCheckBox(g, this); 
Radio Buttonの呼び出しは
 CheckBox paint   UIManager.getInstance().getLookAndFeel().drawRadioButton(g, this); 
このコードからUICManagerというクラスを引き出しました.UICManagerという種類の役割は移植のためのパッケージです.一例モードを使います.
UAIManagerというクラスで注意する方法は二つあります.
 UIManager        /**

     * Returns the currently installed look and feel
     *
     * @return the currently installed look and feel
     */
    public LookAndFeel getLookAndFeel(){
        return current;
    }

    /**
     * Sets the currently installed look and feel
     *
     * @param plaf the look and feel for the application
     */
    public void setLookAndFeel(LookAndFeel plaf){
        current.uninstall();
        current = plaf;
    }
この二つの方法はコンポーネントRenderのキーであり、もし自分でセットの表現を実現したいなら、Look AndFeelのサブクラスを実現して、set Look AndFeelを通じてUImanagerに伝えます.このような方法も高度パッケージです.
UICManagerではデフォルトのLook AndFeelはDefault Look AndFeelという類で、これもコンポーネントのデフォルトの表現方法です.
上記の分析を通して、ここでは一例の設計モードとproxyの設計モードを使っています.具体的な流れは:
1、UICManagerは、プログラム初期化前に、異なるプラットフォームによってLook AndFeelの実例を呼び出しますが、各プラットフォームのLook AndFeel類において、各種UIコンポーネントの描画方法を実現します.この時はproxyデザインを使います.2、各種UIコンポーネントはUICManagerの対応するDRaw方法を調整するだけでいいです.この時は一例の設計モードを使います.
つまり下の図です
もしソフトウェアが移植性のためなら、このような実現方法を参考にしてもいいです.移植性はもちろん多くの方法で実現されています.もしより良い方法があれば、メール議論を歓迎します.
付:SVNから直接署名されたLWUITTコードはnetbeansに適していますが、Eclipseを使ってLWUIDを開くと、以下のようなエラーメッセージがあります.
The method  方法名is defined in in inheritype and an enclosing scope
この場合はエラーコードの前に「this.」を追加すればいいです.例えばForm.javaの中のMenuBar()の構造関数の中で
setLayout(new GridLayout(1, 3));
「defined in an inhersited type and an enclosing scope」の異常を報告します.コードを次のように変更すれば、エラーが発生しません.赤い部分は後から追加します.
 
this.setLayout(new GridLayout(1, 3));
いくつかの名詞の定義
Singleton pattern(単一例モード):  http://en.wikipedia.org/wiki/Singleton_pattern
Compsite pattern:  http://en.wikipedia.org/wiki/Composite_pattern
Proxy pattern(代理モード):  http://en.wikipedia.org/wiki/Proxy_pattern