Lightweight User Interface Toolkit (LWUIT) 为 Java ME UI 开发人员带来了许多令人印象深刻的功能。Style(风格)、Theme(主题)和 Painter 正是这样三种功能,它们可以方便开发非常吸引人且独立于设备的视觉元素。在本文中,我们将介绍如何使用它们,并探讨一些细微的问题。

我们已经使用 Sprint Wireless Toolkit 3.3.1 开发了演示应用程序。此工具包不仅提供了对 LWUIT 的良好支持,它还提供了许多非常有趣的设备仿真器,比如 HTC Touch 和 Samsung Instinct 的仿真器。如果您希望尝试使用 LWUIT,我强烈建议您在计算机上安装 Sprint WTK。

风格

Style(风格)的概念是 theming(主题)构建的基础。Style 的本质是集中定义每个组件的视觉特征。除了其物理设计(比如其形状),窗口小部件的外观可以根据若干共同属性来定义:

  • Background and foreground colors(背景色和前景色):每个组件有四个颜色属性:两个用于背景,两个用于前景。当组件准备好激活时,该组件被认为处于选中状态。当按钮接受焦点时,例如,它处于选中状态,可以通过单击操作来激活它。一个组件可以使用两种背景颜色来分别表示选中状态和未选中状态。同样,也可以根据两种状态分别定义前景色(通常是用于组件上的文本的颜色)。

  • Text fonts(文本字体):可以使用该平台支持的标准字体样式显示文本,也可以使用 bitmap 字体。每个组件的字体可以通过其风格对象设置。

  • Background transparency(背景透明度):组件背景的透明度可以设置为从完全不透明(默认设置)到完全透明。整数值 0 对应完全透明,而 255 对应完全不透明。

  • Background image(背景图片):默认情况下,组件的背景没有任何图片。但是,该设置可用于指定用作背景的图片。

  • Margin and padding(边距和填充):组件的可视布局(源自 CSS Box 模型)定义边距和填充。图 1 显示了 LWUIT 环境中术语 margin(边距)和 padding(填充)的意思。注意 content area(内容区域)用于显示基本内容,比如文本或图片。Style(风格)允许分别设置四个方向(顶部、底部、左边和右边)的 margin(边距)和 padding(填充)。


    图 1. 组件布局

  • (背景 painter):特殊用途的 painter 对象可用于自定义一个或一组组件的背景。

Style 类代表在应用程序中使用的每个组件的这些属性的集合,并且拥有相应的存取(accessor)方法。另外,当特定组件的 style 对象被更改时,该类还可以通知已注册的侦听器。

当组件被创建时,一个默认的 Style 对象会与之关联。对于任何重要应用程序,都需要修改视觉属性。一种方法是使用单独的 setter 方法。,例如,组件(thiscomponent)的背景色必须更改为红色,则可以使用以下代码:

thiscomponent.getStyle().setFgColor(0xff0000);

第二种修改默认风格设置的方法是创建一种新的风格,然后将其挂接到相关的组件。Style 类拥有允许指定大多数属性的构造函数。以下代码片段设置了一个组件的新风格。

Font font = Font.createSystemFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font.SIZE_LARGE);byte tr = (byte)255;Style newstyle = new Style(0x00ff00, 0x000000, 0xff0000, 0x4b338c, font, tr);thiscomponent.setStyle(newstyle);

该代码设置了新的前景和背景色、文本的字体以及背景透明度。此处使用的构造函数格式如下:

Style(int fgColor, int bgColor, int fgSelectionColor,int bgSelectionColor, Font f, byte transparency)

该构造函数还有另外一种形式,除了上述属性之外,它还允许设置图片。该构造函数不支持的属性将需要通过各自的 setter 方法来设置。

最后,通过使用 主题,还可以设置组件中所有类(比如,应用程序中的所有标签)的视觉属性,详见下文。

使用风格

现在,我们应该实现了一个简单的显示效果。接下来,我们介绍如何使用风格来指定组件的外观。我们的应用程序将提供一个组合框,如图 2 所示:

图 2. 一个简单的组合框

此处显示的该组合框的所有属性都是默认值。唯一的例外是前景选择颜色,必须更改该颜色,以提高选中项的可见性。同样,包含该组合框的窗体只修改了一个属性——它的前景色。以下代码显示了如何创建该窗体:

 . . .//create a form and set its titleForm f = new Form("Simple ComboBox");

//set layout manager for the form//f.setLayout(new FlowLayout());

//set form background colourf.getStyle().setBgColor(0xd5fff9); . . .

代码的头两行是不言自明的,AWT/Swing 开发人员应该非常熟悉。第三行设置窗体的背景色属性。

该组合框也使用类似的方式来实现:

// Create a set of itemsString[] items = { "Red", "Blue", "Green", "Yellow" };

//create a combobox with String[] itemsComboBox combobox = new ComboBox(items);

ComboBox 是 List 的子类,需要使用支持的数据结构。这里我们使用一个字符串数组来代表该数据结构。

准备好组合框后,我们要更改其前景选择颜色,以提高可读性。所以像对窗体所做的一样,我们写了如下一行代码:

combobox.getStyle().setFgSelectionColor(0x0000ff);

但是,当我们编译代码并运行的时候,结果非常让人吃惊——前景色保持不变!它对窗体行得通,那为什么对组合框行不通呢?为了解释这个问题,我们需要记住 LWUIT 的基本结构。像 Swing 一样,LWUIT 是围绕 MVC 概念设计的。所以呈现组件的实体和组件本身逻辑上是分离的 。同样,组合框的呈现对象需要是 Component 的子类,这表示它将拥有其自己的风格。每个组合框创建时都有其默认的呈现器,它是 DefaultListCellRenderer 的一个实例。当绘制组合框时,使用的风格属于该呈现器,这就是在组合框的style 对象中设置前景选择颜色行不通的原因。为了使该设置生效,我们必须修改呈现器的 Style 对象:

//set foreground selection colour for//the default combobox renderer//this will workDefaultListCellRenderer dlcr = (DefaultListCellRenderer)combobox.getRenderer();dlcr.getStyle().setFgSelectionColor(0x0000ff);

这一次,当编译该代码时,就可以正常工作了。

在以上部分,我们看到了如何为组件设置单个视觉属性。在有大量 UI 组件的应用程序中,为每个组件设置属性将会是一项庞大的任务,而且容易出错。Theme(主题)允许我们(在一个地方)设置组件的所有类的属性。这不仅简化了为某个特殊类型的所有组件设置属性的任务,而且可以确保任何新添加的组件和应用程序中所有其他同类组件看起来一样。因此 Theme 跨越应用程序的所有屏幕建立了一致的视觉效果。

Theme 是由 key-value 对(其属性为 key,其值为相应的值)组成的列表。列表中的任何项都类似以下格式:

Form.bgColor= 555555

该项指定应用程序中所有窗体的背景色为 RGB 格式的 (hex) 555555。每个主题都被打包为一个 resource(资源)文件,它也可以承载其他项,像用于字体的图片和位图。LWUIT 下载束包含一个 resource editor(资源编辑器),它提供了一种简单的方法来创建主题,并将其打包为一个资源文件。该编辑器可以在该束的 util 目录中找到。双击图标它,该编辑器将会如下所示打开。Resource Editor 也集成到了 Sprint WTK 3.3.1 中,可以通过选择 File -> Utilities -> LWUIT Resource Editor 来访问,如图 3 所示。

图 3. Resource Editor

要创建一个主题,双击左窗格上的 + 按钮,则会打开一个用于输入主题名称的对话框。如图 4 所示。

图 4. 创建新主题

当您单击 OK 时,新主题的名称会显示在左窗格中。单击此主题标签,在有窗格中会出现一个空白主题,如图 5 所示。

图 5. 空白主题

要填充该空白主题,单击 Add 按钮,则会打开 Add 对话框。您可以在此对话框顶部的组合框中选择一个组件和属性。在图 6 中,选中的组件是一个窗体,选中的属性是背景色。该颜色的 RGB 值可以作为十六进制字符串输入提供的空白处。您也可以单击该空白旁边的颜色盒来输入颜色值。这会打开一个 color chooser(颜色选择器),选中颜色的值可以直接从中输入对话框中。

图 6. 将项添加到主题

单击 OK 按钮,该项会出现在主编辑器窗口的右窗格。注意:可以通过使用相应的按钮编辑或删除项。所有项都完成后,您可以通过选择 File -> Save As 将其保存。如果您使用的是 Sprint WTK,那么应用程序的资源文件必须位于其 res 文件夹。

既然我们已经知道了如何创建主题,下面我们来看一个展示其使用的演示。本部分的演示也有组合框,但是比我们刚才看到的将更加精美。图 7 展示了此演示屏幕。注意:现在该窗体有一个背景图片,并且组合框是围绕复选框构建的。同样,标题栏(在窗体顶部)和菜单栏(在底部)也有与默认颜色(白色)不同的背景颜色。

在查看引起外观差异的主题前,让我们快速检查一下用于制作该屏幕的代码。

//initialise the LWUIT Display//and register this MIDletDisplay.init(this);

try {//open the resource file//get and set the themeResources r = Resources.open("/SDTheme1.res");UIManager.getInstance().setThemeProps(r.getTheme("SDTheme1")); }catch (java.io.IOException e) {//if there is a problem print a message on console//in this case default settings will be usedSystem.out.println("Unable to get Theme " + e.getMessage()); }

//create a form and set its titleForm f = new Form("ComboBox Example");

//set layout manager for the formf.setLayout(new FlowLayout());

//create two sets of itemsString[] items = { "Red", "Blue", "Green", "Yellow" };String[] items2 = {"Sky", "Field", "Ocean", "Hill", "Meadow"};

//create two comboboxes with these itemsComboBox comboBox = new ComboBox(items);ComboBox comboBox2 = new ComboBox(items2);

//create new instances of CbPainter//and set them to combo boxes//so that a checkbox will be //the basic building blockCbPainter cbp = new CbPainter();comboBox.setListCellRenderer(cbp);

CbPainter cbp2 = new CbPainter();comboBox2.setListCellRenderer(cbp2);

//add the two combo boxes to the formf.addComponent(comboBox);f.addComponent(comboBox2);

//create an "Exit" command and add it to the formf.addCommand(new Command("Exit"));

//set this form as the listener for the commandf.setCommandListener(this);

//show this formf.show();

最开始的时候,我们看到如何从资源文件中提取主题。然后为 UIManager 实例设置该主题。这里我们已经安装了开始的主题。但是当匆忙设置该主题后,屏幕上窗体的一些组件可能会看不见,而且在这些组件上设置主题的效果无法预测。为了确保即使看不见的组件也适当地更新了它们的风格,您应该调用 refreshTheme 方法:

Display.getInstance().getCurrent().refreshTheme();

窗体和组合框是和 前一部分 中的例子一样创建的。没有代码向此演示添加视觉效果,因为所有属性都是在主题中指定的。这里不同的是,我们设置了我们自己的呈现器,而不是通过默认的呈现器来绘制组合框。这在代码中用突出的部分来显示。这些自定义呈现器使组合框看起来不一样。

呈现器本身非常简单。它所要做的是就是实现接口 ListCellRenderer 中指定的方法。由于我们想要我们的组合框封装复选框,该呈现器扩展了 CheckBoxDefaultLookAndFeel 类的 drawComboBox 方法使用该呈现器获得用于绘制组合框的组件。在这种情况下,这样获得的组件是一个复选框,如以下代码所示。

//objects of this class will be used to paint the combo boxesclass CbPainter extends CheckBox implements ListCellRenderer{public CbPainter() {super(""); }

//returns a properly initialised component//that is ready to draw the checkboxpublic Component getListCellRendererComponent(List list,Object value,int index,boolean isSelected) {setText("" + value);if (isSelected) {setFocus(true);setSelected(true); }else {setFocus(false);setSelected(false); }

return this; }

//returns the component required for drawing//the focussed itempublic Component getListFocusComponent(List list) {setText("");setFocus(true);setSelected(true);

return this; }}

组合框可以具有多种样式,而不仅仅是纯列表或复选框。他可以围绕一些其他的标准组件,或者甚至是有自己独特外观的新组件来构建。图 8 展示了一个拥有单选按钮呈现器的组合框

图 8. 具有单选按钮呈现器的组合框

要查看定义我们的演示的外观的主题,您将需要在计算机上安装 Resource Editor。启动 LWUIT 附带 或者集成到 Sprint Toolkit 中的 Resource Editor。打开 Resource Editor 后,选择 File -> Open 找到并打开资源文件。Resource Editor 将在左窗格的 Themes 下面显示 SDTheme1。单击 SDTheme1 将在右窗格中显示该主题的详细信息,如图 9 所示。

图 9. 该演示的主题

首先要注意的一点是,在顶部有一个项是以白色文字显示的。所有这样的项都是默认的。在我们的例子中,唯一特定于组件的字体设定是用于软件按钮的——左下角的 Exit 按钮。窗体标题和组合框字符串的字体没有定义。这些字体将根据默认设置呈现。

在我们较早的例子中,我们看到文本的选择颜色必须在呈现器中设置。在当前的例子中,我们知道呈现实际上是由复选框呈现器完成的。所以已经为复选框定义了背景和前景色,实际上,呈现文本的颜色和文本背景(都有接受焦点和不接受焦点两种状态)是根据这些定义。如图 10 所示。

图 10. 前景和背景颜色

在上图中,我们可以看到复选框透明度值 127 的效果(半透明)。由于该设置,下拉列表中的三个未选中的项呈中灰色。您可以更改该值,看看这些背景如何改变。顺便说以下,当您更改主题时,没必要重新构建应用程序。只需保存资源文件并单击 Run。

新主题安装好后,除了通过使用 Style 类的某个 accessor 方法手动更改的那些属性(之前 讨论过的)外,所有的可用的风格都会更新。但是,如果您想要新的主题对那些甚至手动更改的属性有效,那么使用 Style 中的某个 setter,它有两个参数,第二个是一个布尔变量。例如:

setFgColor(int fgColor, boolean override);

如果当属性被手动更改时,该布尔参数被设置为 true,那么在新主题中指定的值也将覆盖手动设置的值。代码如下所示:

thiscomponent.getStyle().setFgColor(0xff0000, true);

Painter

Painter 界面允许组件的背景按您所想的显示。回忆一下我们关于风格的讨论,我们看到其中一个属性是 background painter(背景 painter)。在这部分,我们将看到如何使用一个简单的背景 painter。

参考我们的演示截屏,绘制文本的背景颜色无法通过风格或主题更改。当我们分析组合框(如图 11 所示)的结构以及呈现它的顺序时,原因变得很清楚。

图 11. 组合框的结构

当组合框需要重新绘制时(比如,由于它刚接受了焦点),以下事件就会按顺序进行。

  1. 删除旧的组合框。方法是绘制一个同样大小的填满的矩形,其透明度为 0(完全透明)。
  2. 然后绘制复选框选择和文本。
  3. 接着绘制组合框按钮。
  4. 最后,绘制组合框边框。

现在我们看到第一步之后,没有重新绘制组合框背景。所以这部分仍为完全透明的层,显示窗体的背景。您可以在主题中更改窗体的背景色,并且您将看到此颜色也将变为组合框的背景颜色。

如果我们现在想要组合框背景有一个不同的颜色(或者图案、图片),我们需要使用 Painter。我们应该看到一个简单的 painter 的样子,以及如何使用它。

public class ComboBgPainter implements Painter{private int bgcolor;

public ComboBgPainter(int bgcolor) {this.bgcolor = bgcolor; }

public void paint(Graphics g, Rectangle rect) {//probably redundant //but save the current colour anywayint color = g.getColor();

//set the given colourg.setColor(bgcolor);

//get the position and dimension //of rectangle to be drawnint x = rect.getX();int y = rect.getY();int wd = rect.getSize().getWidth();int ht = rect.getSize().getHeight();

//draw the filled rectangleg.fillRect(x, y, wd, ht);

//restore colour settingg.setColor(color); }}

该代码非常简单——它所做的是,使用传递给构造函数的颜色绘制一个填充的矩形。该矩形在 rect 定义和位置和方向绘制。

我们现在要做的是,将该 painter 钩挂到需要描绘其背景的组合框。我们通过在实例化两个组合框的代码后添加突出显示的行来完成。注意:将只描绘一个组合框的背景。

//create two comboboxes with these itemsComboBox combobox = new ComboBox(items);ComboBox combobox2 = new ComboBox(items2);

//set the painter combobox.getStyle().setBgPainter(new ComboBgPainter(0x4b338c));

图 12 显示左侧的组合框的背景已经按预期进行了绘制。如果还希望描绘另一个组合框的背景,我们将使用同一个 painter。实际上,我们可以创建 painter 的实例,然后在所有组合框中设置同一实例。

图 12. 绘有背景的组合框

结束语

我们已经了解了如何借助 LWUIT 平台,使用 StyleTheme和 Painter 来创建一组有视觉吸引力的统一化组件。最近 LWUIT 已经开放了源代码。详细研究这些源代码将会是一种令人陶醉的体验,而且可以帮助您合理地利用该库并实现丰富的用户体验。

  • src_codes.zip:演示应用程序的源代码和源文件。
  • "An Introduction to Lightweight User Interface Toolkit (LWUIT)":LWUIT 概述。
  • Lightweight User Interface Toolkit (LWUIT) 项目主页:提供了到源代码的链接。
  • LWUIT 下载包
  • Sprint Wireless Toolkit 3.3.1 可以从 此处 下载。

Biswajit Sarkar 是一位致力于可编程自动化行业的电子工程师。

使用 LWUIT 的风格、主题和 Painter 特性相关推荐

  1. 43套高质量PPT模板—创意风格主题

    43套高质量PPT模板-创意风格主题 下载链接:https://download.csdn.net/download/cenjiajiu/13195843 风格预览:

  2. Source Insight 4.0 大佬风格主题搭配风格

    Source Insight 4.0 大佬风格主题搭配风格 感谢这位大佬的奉献.Source Insight 4.0,安装破解非常简单,奉上国内和谐文件.连接如下,下载连接 https://pan.b ...

  3. 安卓手机主题软件_资源|一款安卓实现苹果ios风格主题软件

    手持安卓机的我,有时候也想体验体验苹果iOS桌面. 虽然可以通过下载苹果的壁纸/图标来美化,不过桌面布局还是得用第三方启动器来实现. 啼咪给大家带来一款安卓实现苹果iOS风格主题软件:X桌面 X桌面介 ...

  4. electerm可用的 类termius风格主题

    目录 介绍 UI主题配置 终端背景图片 注意 最终效果 介绍 electerm可用的termius风格主题及背景图片,资源来自https://github.com/Hope-IT-Works/elec ...

  5. html仿苹果浏览器,完美仿iPhone风格主题 领航浏览器体验

    1仿iPhone的图标式导航页 手机浏览器这个市场因其使用情况极为广泛和频繁因此吸引了无数厂商进入,不仅是传统的浏览器厂商也有许多新晋的手机软件厂商,其产品也从强调省流量.云概念.操作体验和自主核心. ...

  6. Hexo - Next - Mist 风格主题的美化(二)

    注:两个 _config.yml,一个是 站点配置文件,一个是 主题配置文件. 一.基本美化 0. 更换主题风格 要更改的文件:主题配置文件 如果出现,本地的风格改变了,github 上的风格没改变 ...

  7. JAVA Swing主题 简洁扁平化苹果风格主题

    1.多的不说,直接贴代码了,使用起来非常简单,直接在自己的main方法里贴上如下代码即可看看效果 InitGlobalFont(new Font(UICons.FONT_TYPE, Font.PLAI ...

  8. Satellite7 v2.4 WordPress扁平化风格主题

    Satellite7是一套来自themeforest的wordpress企业主题,这套wordpress主题采用了时下最流行的扁平化设计风格,有点像苹果IOS7系统的风格.主题设计简洁清新,支持视网膜 ...

  9. 华为荣耀v20是android10,华为荣耀v20适配安装EMUI10.0简约风格主题

    在华为荣耀v20手机上适配了一款EMUI10.0系统用的简约主题了,整个主题采用白色搭配天蓝色的基调,整体呈现出非常简约的风格,有喜欢这个风格的主题的,可以进行相关的下载并且体验了. 主题名称:荣耀v ...

  10. android 设置风格主题,Android Theme 常见主题风格详解

    本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助. 目录 [1. 什么是Style,什么是Theme?] [2. 在定义Theme的时候@符号和? ...

最新文章

  1. Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a cl
  2. FPGA中IBERT 核的应用(二)
  3. ASP.NET 设计模式中依赖倒置原则
  4. 【MORE协议】基于MORE的改进协议设计的MATLAB仿真
  5. Anton and Fairy Tale CodeForces - 785C(二分+思维)
  6. zabbix2.2入门教程之编译安装(一)
  7. mysql5.045_数据库升级后goldengate报错,ORA-04045
  8. 求一个数的二进制逆序之后所对应的数
  9. 英特尔与Verizon合力推动5G技术 新网络传输革命即将来临
  10. CSUOJ 1010: Water Drinking
  11. 车用总线技术 | J1939协议实用指南与J1939数据记录方案
  12. 小黄鸟(HTTPCanary)安装及Android高版本CA证书配置
  13. 你适合当leader吗?今晚,我们一起找答案
  14. h5支付——前端需要处理什么?
  15. Ls-Dyna 软件简介 (1)
  16. 中国数学家破解世界百年难题
  17. 2021-2027全球与中国冰箱稳定器市场现状及未来发展趋势
  18. 中国黄芪注射液市场评估与投资战略报告(2022版)
  19. 浅谈JMS--(JMS 的简介)
  20. 【总结】放电管知识大全,看过这篇你都了解了

热门文章

  1. JS div内容滚动条自动上下来回滚动
  2. CAD学习ing——绘制过已知点、指定半径的圆弧
  3. python计算消费总额_11、Python 数据分析-用户消费行为分析
  4. PWN学习记录(1)BUUCTF-test_your_nc
  5. 手机iphone ios android 打开QQ对话框的网页代码!
  6. Mysql 运行原理 (1) - InnoDB 数据存储结构
  7. 关于阅读《重构的时机和方法》这本书所带来的启发
  8. 常用的几个CSS前端效果
  9. 眼图的判断 蒙特卡洛标准差
  10. MySQL每日一练--校园教务系统