Anda di halaman 1dari 58

Building Native iPhone/iPad Applications In Java

Shai Almog & Chen Fishbein

Who are we? Introducing Codename One Lets Build An Application Q&A

Couple Of Hackers
Shai Almog Chen Fishbein

Codename One allows Java developers to build true native apps for all mobile devices Its free & Open Source!


Designer Simulator


Build Server Service Cloud

GPS Maps Camera Video Social Analytics Storage Network Ads L10n Push E-Mail SMS XML JSON Contacts and

Lets Start!

The Todo App

Get Codename One

Download Eclipse Or NetBeans Go to, click

download and setup your update center

New App Wizard

Start new

project in NetBeans or Eclipse

New App Wizard

Pick the
Codename One project type

New App Wizard

Standard project
directory name

New App Wizard

Package name
is really important!

We select the

leather theme & the tab application entries

Lets Look At The App

We have 3 source

StateMachine StateMachineBase Main class

We have one
resource le

Main Class
Callback for
application lifecycle events operates the basics

Initializes and You normally dont

do much here

Statemachine Base
Auto generated by the GUI builder Never touch this class Contains resource le boilerplate code Subclass of UIBuilder

Subclass of
StateMachineBase code should reside invoke methods in StatemachineBase and UIBuilder

Here most of your Override and

Lets run the app & see what we have right now

Resource File
Data le containing
everything the app needs:
Screen designs Images Localization Data les Themes

Go To The GUI Builder Screen

Select The Form, set the title to: Todo

Delete the map container tab (its redundant)

Edit The Tab Titles

Set them to: Tasks, New Task &

Edit The First Tab

Delete the text
area and rename the container to tasksContainer

Set The Layout


should use box layout Y

Layout Managers
Layout managers dene a ow for
components within a Container managers can be nested

Containers can be nested hence layout

Flow Layout
Positions components Allows alignment of
naturally automatic line breaks

components and similarly related features

Box Layout
Positions components in a
line or a column

Components occupy the full

height of the line or the full width of the column

Grid Layout
Positions the components in
equal size within a xed grid of rows/columns

Table Layout
Similar to HTML tables Variable width columns Complex component sizing/spanning

Lets Place a Sample Todo Item

Drag a multi button to the tasksContainer

Select the button & move to the properties tab

Edit the properties

Set line1 to: My task, line2 to: details
set emblem to: [null] & enable the checkbox ag

Add Icon
Select Images->
Quick Add Multi Images image

Select a 100x125 Choose the Very

High option

Multi Image
Multi Images deliver
the right image for every given DPI

Select The Icon In The Multi-Button

Select The Second Container

Update The Tab

Rename the
container: newTask

Remove the

content of the component group

Populate The Tab

Drag to the ComponentGroup 2 text elds & a
button. Drag another ComponentGroup to the to the newTask container & place a button within that

Edit Texts
Double click every entry, remove the
text from the text elds. Set the rst button text to Capture Photo and the second button text to Add Task

Set The Hint

Set the hint attributes of the text elds
to Title & Description respectively

Edit The Names

Name the components in the tree:
titleField, descriptionField, captureButton & addTaskButton.

Note: make sure to press save often!

Lets See What We Built

Press Simulator Button

Lets Start Coding

Select the GUI & select the events tab, select
capturePhoto in the tree & click ActionEvent

Back In The IDE

Add an import: Add a member: Edit the method:
import com.codename1.capture.Capture; private Image photo;

@Override protected void onMain_CaptureButtonAction(final Component c, ActionEvent event) { Capture.capturePhoto(new ActionListener() { public void actionPerformed(ActionEvent evt) { try { if(evt == null){ return; } String path = (String) evt.getSource(); photo = Image.createImage(path); ((Label)c).setIcon(photo.scaledWidth(Display.getInstance().getDisplayWidth() / 3)); c.getParent().getParent().animateLayout(400); } catch (Exception ex) { ex.printStackTrace(); }


Deep In

Exposes variable within the inner class event callback

@Override protected void onMain_CaptureButtonAction(final Component c, ActionEvent event) { Capture.capturePhoto(new ActionListener() { public void actionPerformed(ActionEvent evt) { Standard event callback try { when the photo is if(evt == null){ return; captured or dismissed } String path = (String) evt.getSource(); if(ImageIO.getImageIO() != null) { String photoName = "" + System.currentTimeMillis(); os = Storage.getInstance().createOutputStream(photoName); ImageIO.getImageIO().save(FileSystemStorage.getInstance().openInputStream(path), os, ImageIO.FORMAT_JPEG, imageWidth, imageHeight, 0.9f); os.close(); Image img = Image.createImage(Storage.getInstance().createInputStream(photoName)); photo = photoName; ((Label)c).setIcon(img); c.getParent().getParent().animateLayout(400); } catch (Exception ex) { Log.e(ex); } After making changes that might

} }); }

affect the layout of the UI we need to reow the UI manually. This allows the UI to be more performant.

We scale on the lesystem to avoid loading a VERY large image which will crash a typical phone

Build The Tasks Tab

In the GUI builder click the before show
event button this will add an event that will be invoked before the form is shown:
@Override protected void beforeMain(Form f) { }

Populate The Todos

Add the following imports:
import import import import;; java.util.Vector; java.util.Hashtable;

And the following members:

private Vector<Hashtable<String,String>> todos; private int imageWidth; private int imageHeight;

The Method
@Override protected void beforeMain(Form f) { imageWidth = icon.getWidth(); imageHeight = icon.getHeight(); Container tasksContainer = findTasksContainer(f); tasksContainer.removeAll(); if(todos == null) { todos = new Vector<Hashtable<String,String>>(); return; } for(Hashtable<String,String> entry : todos) { MultiButton mb = createEntry(entry); tasksContainer.addComponent(mb); } }

We fetch the resource le and extract the multiimage of the default icon so we can get the default icon size based on the design

Image icon = fetchResourceFile().getImage("shai_100x125.jpg");

Find methods are automatically generated into statemachine base when we save the resource le

todos = (Vector<Hashtable<String,String>>)Storage.getInstance().readObject("todos");

We load the todo data from application storage

There is no need to revalidate since the form wasnt shown yet. We create a multi button for every stored todo

Creating The Entry

private MultiButton createEntry(final Hashtable<String, String> entry) { final MultiButton mb = new MultiButton(); mb.setCheckBox(true); mb.setTextLine1((String)entry.get("title")); Loading from application storage mb.setTextLine2((String)entry.get("description")); not lesystem! String photo = (String)entry.get("photo"); if(photo != null) { try { mb.setIcon(Image.createImage(Storage.getInstance().createInputStream(photo))); } catch (IOException ex) { Log.e(ex); Print stack trace will be useless on the device but } codename one can send stacks by email from the phone } mb.setEmblem(null); mb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { Adding/removing listeners Container parent = mb.getParent(); parent.removeComponent(mb); allows us to track events on parent.animateLayout(500); components and in the UI todos.remove(entry); Storage.getInstance().writeObject("todos", todos); } }); return mb; We instantly save the data to }


Add A Task
Go back to the GUI builder and click
Action Event for the addTaskButton

And Now The Code

@Override protected void onMain_AddTaskButtonAction(Component c, ActionEvent event) { TextField title = findTitleField(c.getParent()); TextField description = findDescriptionField(c.getParent()); Hashtable<String, String> entry = new Hashtable<String, String>(); entry.put("title", title.getText()); entry.put("description", description.getText()); if(photo != null) { entry.put("photo", photo); } title.setText(""); description.setText(""); findCaptureButton(c.getParent()).setIcon(null); MultiButton mb = createEntry(entry); photo = null; todos.add(entry); Storage.getInstance().writeObject("todos", todos); findTabs1(c.getParent()).setSelectedIndex(0); Container tasksContainer = findTasksContainer(c.getParent()); tasksContainer.addComponent(mb); tasksContainer.animateLayout(500); }

Apple Certicate
You need a developer certicate from
Apple which requires that you pay them. There are instructions in our developer guide

Building For iOS

Right click and send the
iOS debug build (assuming proper certicate and provisioning prole) build server

Get the result from our

On Device Demo

Learn More
Codename One - Blog - Source Code -

Support Forum -