`
*冬眠*
  • 浏览: 982 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

胡言乱语之LWUIT的UI组件代码结构浅析

阅读更多

转:http://www.dongmian.org/2010/02/01/胡言乱语之lwuit的ui组件代码结构浅析/

 

LWUIT: https://lwuit.dev.java.net/ LWUIT是一个轻量级JavaME UI工具包。主要的特性包括:类似Swing 的MVC架构,支持多种布局(Layouts),皮肤更换,字体,触摸屏,动画效果,Rich控件,3D集成,Painter,模式对画 框,I18N/L10N等。值得一提的是LWUIT是sun公司主推的一个图形库,在wtk3.0中已经算是内置的库了。

LWUIT中的组件都在com.sun.lwuit这个包下,所有的组件都是要继承Component这个类,这里Component使用了composite 的设计模式

为了更形象得了解LWUIT的组件体系。可以看下面的UI组件的关系图。

component的继承图图一:Component的继承关系

从图一可以看出,Component分为五大类,分别是

1、Container

2、Label

3、List

4、MediaComponent

5、TextArea

Container与其它的四类组件的不同在于它可以存放子节点,其代码可以下面的方法

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方法又在做什么了?

首先看Container这个类,Container的意思是容器,它的paint方法是对它所包含的每个Componet都有去调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的真正方法.

Container下的子类都会去调用Compaint的paint方法,而Label的子类,除了Spinner外,paint方法都会去调用类似下面的方法

 Label子类的paint方法 

 UIManager.getInstance().getLookAndFeel().drawXXXX(g); 

这里面的drawXXXX代表是对应的组件名,比如说CheckBox,那它调用方法就是

 CheckBox的paint方法

 UIManager.getInstance().getLookAndFeel().drawCheckBox(g, this); 

RadioButton的调用就为

 CheckBox的paint方法 UIManager.getInstance().getLookAndFeel().drawRadioButton(g, this); 

从这的代码就引出了UIManager这个类,UIManager这个类的作用是为了移植而进行的封装的,使用单例模式,

在UIManager这个类中要注意的方法有两个:

 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的关键,如果我们想自己实现一套组件的表现,那么我们只要实现一个LookAndFeel的子类,然后对通过setLookAndFeel把它传给UIManager,这种做法也是高度封装的。

在UIManager中,默认的LookAndFeel是DefaultLookAndFeel这个类,这也是组件默认的表现方法。

通过上面的分析,这里使用了单例的设计模式和proxy的设计模式,具体流程为:

1、UIManager在程序初始化之前会根据不同的平台去调用不同的LookAndFeel的实例,而各个平台的LookAndFeel类里面实现各种UI组件的绘制方法。这时使用proxy设计模式。2、各种UI组件只要去调UIManager的对应的draw方法就可以了,这时使用的是单例的设计模式。

也就是下图

LWUIT的控件调用过程

如果一个软件为了可移植性,那么可以参考一下这种实现方法,当然可移植性还有很多方式来实现,如果有更好的方式欢迎发邮件议论,我的邮箱是:联系方式

附:从SVN中直接签出的LWUIT代码是适合netbeans的,但是如果使用Eclipse打开LWUIT的代码会出如下错误提示:

The method  方法名 is defined in an inherited type and an enclosing scope

这时只要在出错的代码前加一个“this.”就可以了。例如Form.java中的MenuBar()构造函数中

setLayout(new GridLayout(1, 3));


就会报“defined in an inherited type and an enclosing scope” 异常,只要把代码改成如下就不会报错了。红色部分是后面要添加的

 

this.setLayout(new GridLayout(1, 3));

一些名词定义

Singleton pattern(单例模式): http://en.wikipedia.org/wiki/Singleton_pattern

Composite pattern: http://en.wikipedia.org/wiki/Composite_pattern

Proxy pattern(代理模式): http://en.wikipedia.org/wiki/Proxy_pattern

 

 

分享到:
评论

相关推荐

    轻量级UI框架LWUIT最新源代码

    1. **组件库**:LWUIT 提供了多种UI组件,如按钮、文本框、列表、表格等,这些组件都经过优化,能够在有限的资源环境下高效运行。 2. **主题引擎**:通过主题引擎,开发者可以轻松定制应用程序的整体外观和感觉,...

    lwuit最新源代码

    LWUIT不仅包含了基本的UI组件,如按钮、文本框、标签等,还提供了许多高级组件,如滑块、进度条、日历等。同时,LWUIT允许开发者自定义组件,以满足特定项目需求。 6. 事件处理: LWUIT提供了一套完整的事件处理...

    LWUIT j2me UI例子

    这个程序可能会展示一系列使用LWUIT构建的UI组件、布局和主题,让开发者直观地了解LWUIT的功能和用法。可能包括按钮、文本框、列表、表视图、对话框等各种控件的示例,以及不同布局方式的展示。此外,它可能还包括一...

    LWUIT最新源代码

    Sun发布了LWUIT(Light-Weight UI Toolkit)的源代码。项目主页访问:LWUIT。 The Lightweight UI Toolkit (LWUIT) 是一个轻量级JavaME UI工具包。LWUIT类似Swing 的MVC架构, 支持多种布局(Layouts), 皮肤更换, ...

    lwuit 源代码 下载

    LWUIT的源代码下载对于深入理解其工作原理、自定义组件以及优化性能来说非常有价值。 在描述中提到,下载LWUIT源码后,需要将其放入项目的`src`目录下。这通常意味着你需要将源代码解压,并将其组织结构与你的项目...

    J2ME+UI框架LWUIT开发手册

    4. **设计界面**:使用LWUIT的组件来构建应用的UI布局,可以通过代码或者使用可视化设计工具来创建界面。 5. **编写业务逻辑**:结合LWUIT的事件处理机制,实现用户交互逻辑和应用功能。 6. **测试与调试**:在...

    lwuit.rar_J2ME ui_LWUIT_j2me

    同时,LWUIT还支持自定义组件,开发者可以轻松地创建自己的UI组件来满足特定需求。 在动画效果方面,LWUIT提供了一个强大的动画引擎,允许开发者创建平滑的过渡效果、旋转、缩放、淡入淡出等多种动态效果,使得应用...

    lwuit-1.4 源代码

    - **丰富的组件库**:LWUIT包含了一系列预定义的UI组件,如按钮、文本框、列表、表格等,支持自定义样式和行为。 - **皮肤机制**:LWUIT引入了皮肤(Theme)的概念,允许开发者通过XML文件定义UI的外观和感觉,...

    LWUIT1.4源代码加范例(2010/11/5获取)

    1. **组件库**: LWUIT提供了丰富的UI组件,如按钮、文本框、标签、列表、表格等,这些组件轻量级且高度可定制,使得开发者能够创建具有吸引力的用户界面。通过自定义外观和行为,开发者可以实现与设备原生界面风格...

    j2me ui lwuit 1.3

    10. **示例和文档**:LWUIT 社区提供了丰富的示例代码和详尽的文档,帮助开发者快速掌握其使用方法。 通过使用 LWUIT 1.3,开发者可以克服 J2ME 平台上的 UI 开发挑战,创建出与桌面应用相媲美的移动应用界面。如果...

    lwuit_demo_src.rar_DEMO_J2ME lwuit de_LWUIT_lwuit demo

    通过逐行阅读和分析,你可以学习到如何组织代码结构,以及如何使用LWUIT进行事件监听、组件定制和动画效果的实现。 总的来说,这个压缩包是一个宝贵的资源,对于想要学习和精通LWUIT的J2ME开发者来说,它提供了直接...

    LWUIT1.4 最新源代码

    1. **组件库**:LWUIT包含一系列预定义的UI组件,如按钮、文本框、标签、列表、表格、对话框等,这些组件可以进行高度定制,以满足各种设计需求。 2. **主题和皮肤**:LWUIT支持主题和皮肤的概念,允许开发者通过...

    JavaME 轻量级开发框架 LWUIT 源代码

    LWUIT在20100210时发布了最新的源代码,这意味着我们可以深入理解其内部工作原理,自定义和优化UI组件,以及利用这个框架的优势来提升我们的Java ME应用。 LWUIT的核心特性包括: 1. **跨平台兼容性**:LWUIT设计...

    LWUIT 1.3 版本源代码 subversion 签出来的

    LWUIT 1.3 版本是其一个重要的里程碑,它提供了丰富的UI组件和动画效果,极大地提升了移动设备上应用程序的用户体验。 在LWUIT 1.3版本中,开发者可以利用其强大的设计工具进行布局设计,创建出美观且功能丰富的...

    Lwuit入门程序测试一下Demo

    2. **丰富的UI组件**:LWUIT提供了一系列预定义的UI组件,如按钮、文本框、列表、表单等,使开发者可以快速构建美观的界面。 3. **可定制性**:开发者可以通过皮肤(theme)来定制UI的外观和感觉,实现高度个性化的...

    LWUIT

    1. **组件库**:LWUIT 包含了各种常见的UI组件,如按钮、文本框、标签、列表、表单等,这些组件都是轻量级的,适合资源有限的移动设备。同时,它们还支持自定义样式和动画效果,使得UI设计更加灵活多样。 2. **皮肤...

    最新LWUIT_1_5

    LWUIT( Lightweight UI Toolkit )是Java ME(J2ME)平台上的一种用户界面库,专为移动设备设计,提供了一种轻量级、高性能的界面构建工具。它旨在简化和美化在移动设备上的应用程序开发,使开发者能够创建具有丰富...

    LWUIT1.3code.rar_LWUIT

    1. **组件丰富**:LWUIT 提供了多种预定义的UI组件,如按钮、标签、列表、表单、进度条等,这些组件在外观和功能上都经过精心设计,可以满足开发者创建复杂界面的需求。 2. **主题定制**:LWUIT 强调可定制性,允许...

    lwuit 项目代码

    1. **组件库**:LWUIT提供了一系列轻量级的UI组件,如按钮、文本框、列表、表单等,这些组件在内存占用和性能上进行了优化,适合资源有限的移动设备。 2. **样式与主题**:LWUIT引入了主题的概念,允许开发者通过...

    Hello LWUIT——LWUIT开发指南2

    LWUIT(Lightweight User Interface Toolkit)是Java ME平台上的一个开源用户界面库,它为开发者提供了丰富的UI组件和强大的设计工具,使得在移动设备上创建美观、交互性强的应用程序变得更加简单。这篇开发指南将...

Global site tag (gtag.js) - Google Analytics