Thursday, October 31, 2013

CodenameOne project settings and Splash

Project Settings


At the beginning of the project I want to have a higher degree of control of how the application would behave on the phone and therefor I started with basic things (for a native developer) like orientation and fullscreen mode and I ended up spending some time to find the solution. At the end I discovered how to do it:

Fullscreen,

 not supported in the emulator, but available for Android an iOS via the build properties send to the build server. How to change it? Project Properties>CodenameOne> Build Hints add:
 ios.statusbar_hidden
android.statusbar_hidden having both the value "true"
















Orientation,

 this is available during runtime, but I wouldn't bet that it works on all platforms:

  if (Display.getInstance().canForceOrientation())
Display.getInstance().lockOrientation(false);
for portrait lockOrientation(true);
landscape lockOrientation(false);

Now that I got what I wanted lets continue

Splash screen


My goal was to have a background image cover all the screen and on top of it to add things like loading and a brands. I managed to do this by a combination between of themes with GUI or code.

First thing, to have a background image was more complicated than expected, and the way to do this is by adding a custom form selector inside the Themes with the Designer tool (double click the theme.res)



While, having the image in the project is done via Images > Quick Add multi images, where you want to add a big size to cover the HD and the smaller ones will be scaled from it.

The name of the component is important, if you select Form and keep it like this the change of property will be applied to all the Forms. In my case I want this background for Splash only, so I set the name to be SplashForm.

There is a trick, the same custom form selector has to be set for all the Form states, like Selected, Unselected, Pressed and Disabled (maybe not all in case of Splash, but better to be sure :P)



Also important is that for the Form that it is on Splash you change the UIID to SplashForm (instead of Form). If you are using GUI the way to do this is very simple...

For the code (I used the Add GUI > Splash and rewritten it into code):

        Form splash = new Form();
    splash.setUIID("SplashForm");
    BorderLayout bl = new BorderLayout();
    bl.setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE);
    splash.setLayout(bl);
   
    Container c = new Container(new FlowLayout());
    c.addComponent(new Label("petrumo"));
    splash.addComponent(BorderLayout.NORTH, c);
   
    c = new Container(new BoxLayout(BoxLayout.Y_AXIS));
    Container i = new Container(new FlowLayout(Component.CENTER));
    i.addComponent(new InfiniteProgress());
    c.addComponent(i);
   
    i = new Container(new FlowLayout(Component.CENTER));
    i.addComponent(new Label("Loading"));
    c.addComponent(i);
   
    splash.addComponent(BorderLayout.SOUTH, c);

        splash.show();

resulting in a nice Splash screen :)


Topics: #codenameone #setup #splashscreen #fullscreen #orientation

Wednesday, October 30, 2013

CodenameOne the setup

Setup

Setting up the evironment of codenameOne was quite straightforward. I chose the Eclipse route and pretty much followed the instructions.

After linking to the build server, my environment is ready to develop :)

Getting started

Creating the first project is common flow in Eclipse, however at one point you get to the choice of what kind of project do you want:


  • HelloWorld (Visual)
  • HelloWorld (Manual)
  • ...













At the beginning this wasn't so clear what I am about to get with each project. After a few trial and error I discovered that the Visual was giving me a visual project where whatever I can change it in the visual editor and the Manual was an empty one where I have to create the UI structure by code.

What are the differences between this two types of project?



From the folder structure, I would say that the visual project has extra StateMachines in the generated and userclasses folder. I am sure that there are more in the properties and in the themes.res

From the source code point of the view, the instantiation is quite different.
In case of Manual
    public void start() {
     ...
        Form hi = new Form("Hi World");
        hi.addComponent(new Label("Hi World"));
        hi.show();
    }
all the Forms have to be coded
while for the Visual
public void start() {
       ...
        new StateMachine("/theme");      
 }
it is relaying on the instatiation of StateMachine

What is the common part?

By double clicking on the theme.res, you will open the CodenameOne Designer.


Regardless from what kind of project you open the Designer, it looks the same. At least in case of Theme. My initial disappointment was actually that in case of Visual you can create new GUI Builder elements and they will reflect in the project, while in case of Manual you can do the same, but nothing happens to your project. I would prefer not to have this distinction and start by developing visual and later switch to coding.

Workaround


For this potential problem, without too much hassle or need of digging into it, either I created 2 projects one Manual and one Visual in addition to the one I am working on and use them to combine the Visual creation of the items and afterwards translating them into code for a greater control or I convert them in between


How to convert from Visual into Manual (Hello world example)



  • From codenameone_settings.properties remove 

mainForm=Main
package=generated
baseClass=src/generated/StateMachineBase.java
userClass=src/userclasses/StateMachine.java
guiResource=theme.res

  • Delete from theme.res the GUI Element called Main.

  • Delete from the src/ folder the genereted/ and userclasses/ folders

  • From MyApplication 

Replace inside the -> start() the new StateMachine("/theme");

with
 Form hi = new Form("Hi World");
 hi.addComponent(new Label("Hi World"));
 hi.show();
 Make sure your init method is initializing the theme

public void init(Object context) {
        try{
            Resources theme = Resources.openLayered("/theme");
            UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));
       }catch(IOException e){
            e.printStackTrace();
        }
    }


  • Reorganize imports and you are good to go :)



How to convert from Manual into Visual (Hello world example)

The order of doing this is important, so please follow closely


  • Add into codenameone_settings.properties 


mainForm=Main
package=generated
baseClass=src/generated/StateMachineBase.java
userClass=src/userclasses/StateMachine.java
guiResource=theme.res

  • At this point, you want to copy from a GUI project the src/ generated and /userclasses folder, don't bother with already inside they will be overridden. 


Add into theme.res a new GUI Element called Main, whatever form you want, save the theme.res. This cause the /generated files to be overridden.



  • in the MyApplication inside the start() method replace the creation of forms with the 

new StateMachine("/theme");

Also make sure the theme is not initialized inside the init(Object context)

public void init(Object context) {
    }

Now you have Visual project :)


Continued on creating a SplashScreen


Topics: #codenameone #setup #helloworld

Tuesday, October 29, 2013

CodenameOne the beginning

Intro


I attended a presentation about CodenameOne some time ago and since I saw it, I was charmed by the idea and I decided to give it a chance. As any other new technologies, before adopting them I am willing to put it to the test. So, my first question is if I can use it to develop commercial apps requiring a high professional level of quality and customization?

In order to get more information I decided to work on a 'dummy' application and share the learning as I go along.

Continued on setup

Topics: #codenameone, #learn