You are here

Touch J2ME Polish--5. First Application, begin with Loading Splash Screen

Blog Terms: 

If you have used some J2ME applicaitons, e.g. some games, almost all of them will give you one loading splash screen when you start the game, or before you enter the next stage the waiting splash screen will tell you the progress of data loading. The standard solution is to provide a splash screen and do the necessary initialization in a background thread. And if you have done this before, your code will look like this:

//firstly difine one class to draw the logo and string on canvas
    public class SplashCanvas extends Canvas {
    
        protected void paint(Graphics g){
            try {
                icon_start=Image.createImage("/welcome.png");
            } catch (java.io.IOException e) {
                icon_start=null;
                System.out.println("Load image error when initializing Exception happens:" + e.getMessage());
            }
            g.drawImage(icon_start,getWidth()/2, getHeight()/2-15, Graphics.BOTTOM| Graphics.HCENTER);
           
            g.drawString("EasyWMS 1.00", getWidth()/2, getHeight()/2, Graphics.BOTTOM| Graphics.HCENTER );
            g.drawString("Loading...", getWidth()/2, getHeight()/2+15, Graphics.BOTTOM| Graphics.HCENTER );
            splashIsShown=true;
           
        }
        protected Graphics clearScreen(Graphics g) {
              // clear screen
              g.setColor(255, 255, 255);
              g.drawRect(0, 0, this.getWidth(), this.getHeight());
              return g;
             }
       
    }

//will run the splash screen in one background thread, for the further calling
   public class SplashScreen implements Runnable{
        private SplashCanvas splashCanvas;
       
        public void run(){
            splashCanvas = new SplashCanvas ();     
            display.setCurrent(splashCanvas);
            splashCanvas.repaint();
            splashCanvas.serviceRepaints();
            while(!isInitialized){
                try{
                    Thread.yield();
                }catch(Exception e){}
            }
        }     
    }  

//impletement this class as one thread, like this:
//public class genisMIDlet extends MIDlet implements Runnable{
//then give the run method
    public void run(){
        while(!splashIsShown){
            Thread.yield();
        }      
        doTimeConsumingInit();      
        while(true){
            // soft loop          
            Thread.yield();
        }
    }
   
//the splash will keep on displaying 3 seconds and then go to the main form automatically
    private void doTimeConsumingInit(){
        // Just mimic some lengthy initialization for 3 secs
        long endTime= System.currentTimeMillis()+3000;
        while(System.currentTimeMillis()<endTime ){}

        controller=new UIController(this);
        controller.init();
        isInitialized=true;
    }

//at last,  open 2 threads when initialize the application
    protected void startApp() throws MIDletStateChangeException {
        Thread splashthread= new Thread(new genisMIDlet.SplashScreen());
        splashthread.start();

     //now you can also load the data from database or something.....
        Thread thisThread = new Thread(this);
        thisThread.start();
    }

And if there are others progress need to give the user one waiting screen, those code will be write again with differnt string and image. Are you tired? Yes, I am tired of this.Polish provides the de.enough.polish.ui.splash.InitializerSplashScreen for this task. The splash screen shows an image along with an optional string message and initialize the actual application in a backgroud thread.  This is the code example:

package de.enough.polish.sample.splashScreen;

import java.io.IOException;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.lcdui.*;
import de.enough.polish.ui.splash.InitializerSplashScreen;
import de.enough.polish.ui.splash.ApplicationInitializer;;

public class SplashScreenDemo extends MIDlet
//#if !polish.clases.ApplicationInitializer:defined
    implements ApplicationInitializer
//#endif
{
    private Screen mainScreen;
    private Display display;
   
    protected void startApp() throws MIDletStateChangeException {
        this.display = Display.getDisplay(this);
        if(this.mainScreen !=null){
            //the MIDlet has been paused;
            this.display.setCurrent(this.mainScreen);
        }else{
              //the MIDlet is started for this first time
              try{
                  Image image = Image.createImage("/welcome.png");
                  int backgroundColor = 0xFFFFFF;
                  String readyMessage = "Press any key to continue...";
                  //Set readyMessage = null to forward to the next
                  //displayabe as soon as it's available
                  int messageColor = 0xFF0000;
                  InitializerSplashScreen splashScreen = new InitializerSplashScreen(this.display
                  ,image, backgroundColor, readyMessage,messageColor,this);
                  this.display.setCurrent(splashScreen);
              }catch(IOException e){
                throw new MIDletStateChangeException("Unable to load splash image");
              }
        }
    }

    public Displayable initApp(){
        //initialize the application.e.g. read data from record store,etc
        //.......
        //now create the main menu screen:
        //e.g. this.mainScreen = new Form("Main Form");

        this.mainScreen = new Form("Main Form");

        return this.mainScreen;

    }
   
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // TODO Auto-generated method stub
       
    }

    protected void pauseApp() {
        // TODO Auto-generated method stub
       
    }
}
Splash Loading Screen:

Go to the main Form:

Have you seen that, only one function could do everything, creates a new InitializerSplashScreen using the internal default view.
public InitializerSplashScreen(Display display, Image image, int backgroundColor, java.lang.String readyMessage, int messageColor, ApplicationInitializer initializer)The message will be shown in the default font.Parameters:

display - the display responsible for switching screens
image - the image that is shown in the center
backgroundColor - the background color, e.g. white: 0xFFFFFF
readyMessage - the message that is displayed when the application has been initialized
messageColor - the color for the message, e.g. black: 0
initializer - the application initializer that will be called in a background thread

The InitializerSplashScreen can have different views, please refer to the javaDoc.Here is the source code and resource(together with the code in Touch J2ME Polish--4. Test with Polish Example):5splash.rarAnd you can run the jad file view the application example.
Refer:
Book: Pro J2ME Polish, author:Robert Virkus
http://www.j2mepolish.org/javadoc/j2me/index.html

Comments

Hi leelight,
I have a question.
I want to know all the view at splash screen are static? Can I make that view with an animation?

Thanks & BR

Of course you can make the splash screen as animation. If I have time, i can add one example.

Welcome to EASYWMS

Dear Sir:

thanks for teaching me on J2MEPolish, i also want to know how to let it's animation on
splash screen.

Hi, i have a question...

How can i reduced the size of the application?
I build the sample application and the jar size is 416 KB!!!! {:jawdrop:}

Cand this be reduced?

Hi, I used one example from polish, in it resource folder there are many images which I have not used(more than 100kb), you can delete the useless images before compiling(notice some related css style should also be removed). And if you build project with ANT, please find "" in build.xml, to make sure that the value of test if false--- when test is false, ANT will use Proguard to obfuscate the project.

Can you tell me how to build this application from the source code provided. I need to integrate the splash screen into an application am developing. Thanks! My email is willc2k84atgeemaildotcom

I have also tried Polish API.. it made my application of 800kb
While with out it its 132kb..

To use SplashScrenn I would advice for netbeans APIs.. they are really usefull

Hi,

You can obfuscate the jar file using Proguard, even you can do this with in build.xml it will make 800kb jar about 120kb after obfuscation if it does not have much images.

Regards,
Tharindu