65.9K
CodeProject 正在变化。 阅读更多。
Home

运行时通过代码修改 j2mepolish 样式

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2009年1月28日

CPOL

5分钟阅读

viewsIcon

22372

本文展示了如何在运行时通过代码而非CSS文件修改j2me应用程序的j2mepolish样式。

引言

本文将向您展示如何在运行时通过代码修改j2ME应用程序的j2mepolish样式。特别是,本示例将向您展示如何修改应用程序标题栏的样式。我认为这个例子足以让您开始。

我决定写这篇文章,是因为当我遇到这个问题时,我找不到我要找的东西。

在开始之前,我想告诉您,该应用程序是使用eclipse IDE 3.4版本编写的,而polish版本是2.0.4。

最后我想提一下,这个应用程序使用的polish.css文件来自我正在构建的一个更复杂的应用程序,所以您不必太在意它。您只需要关注我在文章下一节将展示的样式。

背景

为了理解本文,我猜您需要一些使用polish来增强视觉效果的j2me应用程序的构建经验。

使用代码

为了开始,我将说明该应用程序实现了MVC模式,并且使用了三个类(控制器和两个视图)。控制器类如下所示。

public class Controller {
    Midlet midlet;
    Display display;
    MainForm mainScreen;
    StyledList styledList;
    public Controller(Midlet midlet){
        this.midlet=midlet;
        display=Display.getDisplay(midlet);
        mainScreen=new MainForm("Main Screen",this);
        styledList=new StyledList("Styled List",List.IMPLICIT,new Style(),this);
    }
    public void showMainScreen(){
        display.setCurrent(mainScreen);
    }
    public void showStyledList(){
        display.setCurrent(styledList);
    }
    public void quitApp(){
        midlet.quitApp();
    }
}

正如您所见,这个控制器类有几个简单的函数。我们有quitApp()函数来退出应用程序,showMainScreen()函数来显示mainScreen表单,以及showStyledList()函数来显示styledList列表。这个列表将包含更改标题栏样式的代码。构造函数初始化了两个视图。从初始化代码可以看出,只有当UI元素派生自polish UI元素(如StyledList)时,才能更改其样式。

接下来要介绍的类是MainForm类。该类的定义如下所示。

public class MainForm extends Form implements CommandListener {

    private Controller controller;
    Command cmdExit;
    Command cmdShowList;
    public MainForm(String title,Controller controller)
    {
        super(title);
        this.controller=controller;
        setCommandListener(this);
        cmdExit=new Command("Exit",Command.EXIT,0);
        this.addCommand(cmdExit);
        cmdShowList=new Command("Styled List",Command.SCREEN,0);
        this.addCommand(cmdShowList);
    }
    public void commandAction(Command cmd, Displayable arg1) {
        if(cmd==cmdExit){
            controller.quitApp();
        }else if(cmd==cmdShowList){
            controller.showStyledList();
        }
    }
}

正如您所见,这个类的唯一目的是将用户引导至样式列表。当您运行应用程序时,您会发现,这个屏幕也显示了标题栏的样式仅为styledList屏幕更改。MainForm屏幕将保留其原始的标题栏样式。

我要介绍的最后一个类是最重要的。这个类包含了将更改标题栏样式的代码。该类的定义如下所示。

public class StyledList
 extends de.enough.polish.ui.List
 implements CommandListener {
    Controller controller;
    Command cmdBack;
    Command cmdChangeTitle;
    Command cmdOldStyle;
    Background oldBackground;
    public StyledList(String title, int listType, Style style,Controller controller) {
        
        super(title, listType, style);
        this.controller=controller;
        this.setCommandListener(this);
        cmdBack=new Command("Back",Command.BACK,0);
        this.addCommand(cmdBack);
        cmdChangeTitle=new Command("Change",Command.SCREEN,0);
        this.addCommand(cmdChangeTitle);
        cmdOldStyle=new Command("Old Title",Command.SCREEN,1);
        this.addCommand(cmdOldStyle);
    }
    public void commandAction(Command cmd, Displayable arg1) {
        if(cmd==cmdBack){
            controller.showMainScreen();
        }else if(cmd==cmdChangeTitle){
            Style style=new Style();
            BorderedRoundRectBackground bg= 
              new BorderedRoundRectBackground(16711680,10,10,16776960,3);
            style.background=bg;
            style.marginBottom=3;style.marginTop=3;
            style.marginLeft=3;style.marginRight=3;
            style.paddingBottom=3;style.paddingTop=3;
            style.paddingLeft=3;style.paddingRight=3;
            style.fontColorObj=new Color(16776960);
            style.layout=Item.LAYOUT_EXPAND|Item.LAYOUT_CENTER;
            Font f=Font.getFont(Font.FACE_MONOSPACE, 
                                Font.STYLE_BOLD,Font.SIZE_LARGE);
            style.font=f;
            this.setTitle(this.getTitle(),style);
            //this.repaint();
        }else if(cmd==cmdOldStyle){
            Style style=new Style();
            //set the font
            Font f=Font.getFont(Font.FACE_PROPORTIONAL,
                                Font.STYLE_BOLD,Font.SIZE_LARGE);
            style.fontColorObj=new Color(14474460);
            style.font=f;
            //set padding and margin
            style.marginBottom=1;
            style.paddingTop=style.paddingBottom=3;
            //set the layout
            style.layout=Item.LAYOUT_EXPAND|Item.LAYOUT_CENTER;
            //set the border
            style.border=new RoundRectBorder(5658216,1,12,12);
            //set the background
            //1. create the foregroung bg
            ImageBackground foregroundBG=
              new ImageBackground(Color.TRANSPARENT,"/omni16.PNG",10,-3,0);
            //2. create the background bg
            PartialGradientBackground backgroundBG=
              new PartialGradientBackground(0,5658216,0,0,100);
            
            //3. create the combined bg
            CombinedBackground combinedBG=
              new CombinedBackground(foregroundBG,backgroundBG);
            ImageBackground foregroundBG2=
              new ImageBackground(Color.TRANSPARENT,"/omni16.PNG",6,3,0);
            CombinedBackground combinedBG2=
              new CombinedBackground(foregroundBG2,combinedBG);
            style.background=combinedBG2;
            //apply the style
            this.setTitle(this.getTitle(),style);
        }
    }
}

在开始解释这个类的代码之前,我想向您展示原始的标题栏样式。我将在这里展示polish.css文件中的CSS以及一个图片来说明它的外观。标题栏的CSS样式如下所示。

titleBottom
{
    type:partial-gradient;
    start:0%;
    end:100%;
    top-color:#000000;
    bottom-color:#565668;
}
titleTop
{
    image:url(omni16.PNG);
    color:transparent;
    anchor:top|right;
}
title
{
    font:titleFont;
    padding-top:3;
    padding-bottom:3;
    margin-bottom:1;
    border
    {
        color:#565668;
        type:round-rect;
        arc:12;
        width:1;
    }
    background
    {
        type: combined;
        foreground:titleTop;
        background:titleBottom;
    }
    layout: hcenter | hexpand;
}

我们这里有一个组合背景。背景的第一部分是titleTop样式。这是一个图像背景,将代表组合背景的前景。第二种样式是titleBottom样式。这是一个部分渐变背景,将代表组合背景的背景部分。标题样式还设置了字体内边距和边框。此标题样式也可以在下面的图片中看到。

original.PNG

正如您所见,图像部分叠加在部分渐变部分之上。

接下来,我将解释StyledList类的代码。您可以看到这个类派生自polish的List类。如果您想在运行时通过代码更改样式,这是必需的。这个类只有三个命令。

第一个命令用于返回到主表单屏幕。

第二个命令用于将当前样式更改为简单的红色背景样式。新的背景是使用代码设置的,这与使用CSS样式设置的原始样式不同。这种新的标题栏样式可以在下图看到。

first.PNG

为了通过代码构建这个背景,我首先实例化了一个Style对象。在此之后,我实例化了一个BorderedRoundRectBackground对象,并将此背景分配给先前实例化的Style对象的背景字段。

Style style=new Style();
BorderedRoundRectBackground bg = 
   new BorderedRoundRectBackground(16711680,10,10,16776960,3);
style.background=bg;

上面构造函数的第一个参数是背景的颜色(红色),第二个和第三个参数代表圆角的宽度和高度,第四个参数代表边框的颜色(黄色),最后一个参数代表边框的厚度。

接下来,我设置了边距、内边距、布局和字体的属性。这些属性使用以下行进行设置。

style.marginBottom=3;style.marginTop=3;
style.marginLeft=3;style.marginRight=3;
style.paddingBottom=3;style.paddingTop=3;
style.paddingLeft=3;style.paddingRight=3;
style.fontColorObj=new Color(16776960);
style.layout=Item.LAYOUT_EXPAND|Item.LAYOUT_CENTER|Item.LAYOUT_VEXPAND;
Font f=Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_BOLD,Font.SIZE_LARGE);
style.font=f;

我做的最后一件事是使用setTitle()函数来应用新的样式。

此样式也可以使用CSS样式设置,如下所示,但由于我想动态更改它们,所以我没有采用这种方法。这是等效的CSS。

title {
    font
    {
        face:monospace;
        size:large;
        color:#ffff00;
        style:bold;
    }    
    background
    {
    type:round-rect;
    arc:10;
    width:3;
    color:#ff0000;
    }
    border
    {
        width:3;
        color:#ffff00;
        type:round-rect;
        arc:10;
    }
    margin:3;
    padding:3;
    layout:center|hexpand|vexpand;
}

为了选择更高级的样式,我们需要使用最后一个命令。通过使用这个最后的命令,我们可以获得以下样式。

second.PNG

样式是通过以下代码构建的。

我首先实例化一个将在最后应用的Style对象。然后我使用以下代码设置内边距、外边距、字体、布局和边框。

Style style=new Style();
Font f=Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE);
style.fontColorObj=new Color(14474460);
style.font=f;
style.marginBottom=1;
style.paddingTop=style.paddingBottom=3;
style.layout=Item.LAYOUT_EXPAND|Item.LAYOUT_CENTER;
style.border=new RoundRectBorder(5658216,1,12,12);

现在唯一剩下的事情就是设置背景。这个背景是一个组合背景,其中包含另一个组合背景。第一个组合背景与本文开头介绍的原始背景相同。然后将此背景用作另一个组合背景的背景,以便定位第二个图像。此背景的代码如下所示。

ImageBackground foregroundBG=new ImageBackground(Color.TRANSPARENT,"/omni16.PNG",10,-3,0);
PartialGradientBackground backgroundBG=new PartialGradientBackground(0,5658216,0,0,100);
CombinedBackground combinedBG=new CombinedBackground(foregroundBG,backgroundBG);
ImageBackground foregroundBG2=new ImageBackground(Color.TRANSPARENT,"/omni16.PNG",6,3,0);
CombinedBackground combinedBG2=new CombinedBackground(foregroundBG2,combinedBG);
style.background=combinedBG2;

构建完此样式后,我使用setTitle()方法将其应用。

就是这样。我希望这篇文章对您有所帮助,并能帮助您修改应用程序中的其余样式。

关注点

值得注意的是,只有当前屏幕的标题样式会发生变化。其余屏幕将保留旧的标题样式。

为了更改所有屏幕的标题样式,一个好的选择是在控制器中设置一个全局样式,并让所有屏幕都使用该样式作为标题栏样式。在应用程序的整个过程中,只有此样式会被修改,并且因为每个屏幕都将持有对这个单一实例的引用,所以每次我们修改它时,更改都应该在所有屏幕中可见。

历史

  • 创建于 2008.12.24。
© . All rights reserved.