You are here

Touch J2ME Polish--6. GUI DIY with CSS style definition

I MUST say firstly that using CSS to define the GUI in J2ME application is a VERY VERY SMART idea!
What is CSS?
Cascading Style Sheets, was widely used in XHTML and webdesigning, the designers cant separate the style from the HTML userinterface, that means the programmer can only do his part of HTML interface designing, and the beautification and decoration of interface could be left to art designer. For example, look at the menu of this page, if one day I am tired of the current style of easywms.com, I DO NOT have to modify the HTML code for each page, I just need modify the css file and every page will change its style. 

Before touching Polish, I cant relate CSS with J2ME even give me 1000 chances to think. But now, erery webdesigner can design mobile applications with J2ME Polish. AHHHHHHHH~~~~ we will lost our JOBs, I hate J2ME Polish! :-P

The css file named polish.css is stored in the resources directory of the project, unless another directory has benn specified in the build.xml file. This file has all the design settings and definitions. One example:

.mainScreen {
    padding: 5;
    padding-left: 15;
    padding-right: 15;
    font-color: #6262d4;
    font-style: bold;
    font-size: large;
    background {
        color: white;
    }
    background-image: url( flames.png );
    background-anchor: left | bottom;
    layout: horizontal-expand | horizontal-center | top;
    screen-change-animation: verticalflash; 
    view-type: dropping;
}
The CSS syntax of Polish is simple, but you should obey the rules. You can find good css example in the sample folder where Polish was installed. Once you defined the style, you could use it for your code. You should use the #style directive for applying the desired styles. This directive contains one or serveral style names that are separated by commas. When serveral style name are given, Polish will use the first availale style. The preprocessor of Polish will select the first available style and inserts it in the following line as the last parameter.

//#style mainScreen, default
Form testForm = new Form("Test Form");

What is Preprocessor?
The Preprocessor we could understand as one Polish buildin machine, it can change the source code before it is compiled. Why changes the source code? Because Polish has extended every original Class in J2ME, such as the high level GUI, Form, Item, Gauge and something else. The Polish must change your code to ITS code format, so that the special effect in GUI could be displayed. The command of Preprocessor are always in the comment lines, the normal emulator will ignore the comment lines but Polish not. The adventage is that one day if you dont use Polish, your source will run without any problem.

What means "inserts it in the following line as the last parameter"?
When Polish Preprocessor read the source code and it finds this line: //#style mainScreen, default
It knows,"The following line will use a CSS style." I have said, the source code will be changed before it is compiled. The next line code will be changed, and the style parameter will be inserts as the last parameter.
Form testForm = new Form(String "Test Form", Style style);
You will never see the processing underground, you need not care about it.

Ok, I will give you one simple Midlet example:
package www.easywms.com;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class TestFormInclude extends MIDlet implements CommandListener{
    /**
     * Creates a new MIDlet.
     */
    public TestFormInclude() {
        super();
    }

    private Form form;
    private Command exitCmd = new Command("Exit", Command.BACK, 1 );
   
    protected void startApp() throws MIDletStateChangeException {
        //#style mainScreen
        form = new Form("Form Include");
       
        form.addCommand(this.exitCmd);
        form.setCommandListener( this );
       
        Display display = Display.getDisplay( this );
        display.setCurrent( form );

    }
   
    protected void pauseApp() {
        // ignore
    }

    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
        // nothing to free
    }

    public void commandAction(Command cmd, Displayable disp) {
        if (cmd == this.exitCmd) {
            notifyDestroyed();           
        }

    }

}

The code will create one Form with one catty background and animation when you load it. No programming, just defined the CSS file!

Ok, new Prolem comes always with the success. If you are not a OPP(Oriented Process Programming) zerlot, you could make new class that extend Form, so that not everything is in one Midlet Class and you code will have a better structure. I modified the code:

TestFormClass.java
package www.easywms.com;

import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class TestFormClass extends MIDlet{
    /**
     * Creates a new MIDlet.
     */
    public TestFormClass() {
        super();
    }

    private MyForm myform;
   
    protected void startApp() throws MIDletStateChangeException {
        //#style mainScreen
        myform = new MyForm("Form Include", this);
       
        Display display = Display.getDisplay( this );
        display.setCurrent( myform );
    }
   
    protected void pauseApp() {
        // ignore
    }

    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
        // nothing to free
    }

}

MyForm.java
package www.easywms.com;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;

public class MyForm extends Form implements CommandListener{

    private Command exitCmd = new Command("Exit", Command.BACK, 1 );
    private MIDlet midlet;
   
    public MyForm(String title, MIDlet midlet_){
        super(title);
        midlet = midlet_;
        this.addCommand(this.exitCmd);
        this.setCommandListener( this );
    }
   
    public void commandAction(Command cmd, Displayable arg1) {
        if (cmd == this.exitCmd) {
            midlet.notifyDestroyed();           
        }
       
    }
}

Run the Midlet with polish, we will get this error:
       [javac] E:\My Documents\WorkSpace2\polishform\build\test\Generic\DefaultColorPhone\en_US\source\www\easywms\com\TestFormClass.java:24: cannot find symbol
       [javac] symbol  : constructor MyForm(java.lang.String,www.easywms.com.TestFormClass,de.enough.polish.ui.Style)
       [javac] location: class www.easywms.com.MyForm
       [javac]         myform = new MyForm("Form Include", this, de.enough.polish.ui.StyleSheet.mainscreenStyle );
       [javac]                          ^
       [javac] 1 error

From the error you could understand how Polish insert the style as the last parameter. What is the problem? Please remove the //#style mainScreen in TestFormClass.java and add this line in MyForm class.

TestFormClass.java
    protected void startApp() throws MIDletStateChangeException {

        myform = new MyForm("Form Include", this);
       
        Display display = Display.getDisplay( this );
        display.setCurrent( myform );
    }

MyForm.java
    public MyForm(String title, MIDlet midlet_){
        //#style mainScreen
        super(title);
        midlet = midlet_;
        this.addCommand(this.exitCmd);
        this.setCommandListener( this );
    }

Run the code, ok, the catty comes back. What is the reason? I understood this way: If you create a new class outside the Midlet class and use it, the midlet do not clear how the class was defined even you give the class a style and the Polish Preprocessor can not perform it. You should give it the style inside the new class, and the Polish Preprocessor knows clear. If you think my idea is wrong, please tell us the clear reason.

But I am one aesthete, I would not define the style inside the Form class, that when I use it, it will be displayed in only one certain style. And if I use it as the first way, I cant give the Form a different style everytimes. And I found one way. Modify the code.

TestFormAll .java
package www.easywms.com;

import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class TestFormAll extends MIDlet{
    /**
     * Creates a new MIDlet.
     */
    public TestFormAll() {
        super();
    }

    private AllForm allform;
   
    protected void startApp() throws MIDletStateChangeException {
        //#style mainScreen
        allform = new AllForm("Form Include", this);
       
        Display display = Display.getDisplay( this );
        display.setCurrent( allform );
    }
   
    protected void pauseApp() {
        // ignore
    }

    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
        // nothing to free
    }

}

AllForm .java
package www.easywms.com;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;

import de.enough.polish.ui.Style;

public class AllForm extends Form implements CommandListener{

    private Command exitCmd = new Command("Exit", Command.BACK, 1 );
    private MIDlet midlet;
   
    public AllForm(String title, MIDlet midlet_){
        //#if polish.usePolishGui
        //#style mainScreen?
        //# this( title, midlet_);
        //#else
        this( title, midlet_,null );
        //#endif
    }
   
    //#if polish.usePolishGui
    public AllForm(String title, MIDlet midlet_, Style style){
        //#if polish.usePolishGui
        //# super( title,style );
         //#else
        super(title);
        //#endif
        midlet = midlet_;
        this.addCommand(this.exitCmd);
        this.setCommandListener( this );
    }
    //#endif
   
    public void commandAction(Command cmd, Displayable arg1) {
        if (cmd == this.exitCmd) {
            midlet.notifyDestroyed();           
        }
       
    }
}

It seems not required to explain the Preprocessor command lines in the comment lines, it is very clear. If use PolishGui, then use AllForm(String title, MIDlet midlet_, Style style), which is the error tell us. If not, use the original AllForm(String title, MIDlet midlet_).

I wasted 3 days to solve this problem, I hope it can help you out.

The source code could be download here.

Refer:
ProPolish, Robert Vircus
Polish Sample

Comments

Great tutorial! Simple and to the point! I've just discovered J2ME Polish and I think its awesome!

THis is really great tutorial about j2mepolish
I was looking for this kind of tutorial....for a long time
finally I found it
thanks...
keep going

This page is great. Im facin some problem trying to use polish.css and maybe you had the same problem;:
symbol : variable mainscreenStyle
location: class de.enough.polish.ui.StyleSheet
settingsForm = new de.enough.polish.ui.Form("Settings", de.enough.polish.ui.StyleSheet.mainscreenStyle );

I'm gettings this error every time and I can't compile using styles, I also don't see the textfields and choicegroups I add to the form!
Any help would be appreciated,
Regards,
Pepe

Hi, did you use my code here or yours own? it could be the following problems:

1, make sure the mainScreen css style has been defined in polish.css

2, add css style as this,

//#style mainScreen
public
settingsForm(MIDlet midlet_){
super("Settings");
midlet = midlet_;
this.addCommand(this.exitCmd);
this.setCommandListener( this );
}

 

3, Or as this:

public
settingsForm(MIDlet midlet_){
//#style mainScreen
super("Settings");
midlet = midlet_;
this.addCommand(this.exitCmd);
this.setCommandListener( this );
}

4, do NOT use like this, whenyou create instance of settingsForm

//#style mainScreen(WRONG)
settingsForm settingsForm = new settingsForm(midlet);

Thanks

You solve my problem with your tutorial.
And the last comment was useful too.

Thank you all of you.

Cheers

very nice article thank you very much....

Thanks for the tutorial i think its very precise and carried all the relevant stuff , just giving an overview of the all methods for CSS using these tools is also a complication.

Hello,

I am trying to implement AutoCompletion / Inline Text Editing features using J2ME Polish for one of our Applications. I appreciate if I could get some hints / pointers to enable the same.

My development platform is JRE 1.6 with NetBeans 6.8, utilising J2ME-Polish-2.1.2 ver.

Thanks and I look forward to hearing from you,

Narasimha

See if this will help
http://www.j2mepolish.org/cms/leftsection/documentation/design/visual-guide/gui-item-textfield.html

Hi, I found this article very nice and put some rays on what are the possibilities and what can be achieved using Polish in some way. I have query related to the conversion of ME midlet to Polish midlet. I mean I have developed a midlet using Sun's pure Java ME Api. But the GUI is not much attractive. So if I use Polish, and if I want to convert current app to the Polish, what can I do?
Just by importing Polish libraries and working on CSS related stuff will work? or Do I need develop from the scratch?
Can I have any link or screen shots about "what kind of GUIs can be designed using Polish?"

Best Regards.

Wait, I caonnt fathom it being so straightforward.

That saves me. Thanks for being so sesnilbe!