Visage Android Hands-on Lab (OSCON)
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Visage Android Hands-on Lab (OSCON)

on

  • 1,649 views

Lab session given at OSCON Java 2011:...

Lab session given at OSCON Java 2011:
Visage is the successor to the JavaFX Script Language, a domain-specific language for writing UIs. It excels at rapid application design and can be used on any platform that supports Java. In this lab you will have an opportunity to write Visage applications that deploy to and run on Android mobile devices. No prior experience with Android or Visage development is required.

Statistics

Views

Total Views
1,649
Views on SlideShare
1,609
Embed Views
40

Actions

Likes
1
Downloads
14
Comments
0

1 Embed 40

http://lanyrd.com 40

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Visage Android Hands-on Lab (OSCON) Presentation Transcript

  • 1. Visage AndroidHands-on LabStephen ChinChief Agile Methodologist – GXSOSCON Java Program Chairhttp://steveonjava.com/Tweet: @steveonjava
  • 2. How This Session Works Team A Team B Team C
  • 3. The Visage Language § Statically Compiled Language § Based on F3 / JavaFX Script § Planning Support for Different Platforms: -  JavaFX 2.0 -  Android -  Apache Pivot>  “Visage is a domain specific language (DSL) designed for the -  Flex express purpose of writing user interfaces.” -  JSF 3
  • 4. What Does Visage Look Like? Stage { var input:TextBox; title: bind input.text Scene { input = TextBox { color: #DDCC33 } } }   4
  • 5. UI Focused Language Features§ Declarative Object Construction -  Code looks like the UI it is representing.§ Data Binding -  Variables can be bound to UI state, allowing automatic updates and behavior to be triggered.§ UI Definition Literals -  Built-in literal syntax for colors, angles, lengths, and durations§ Null Safety -  Application logic will proceed even if intermediate variables are undefined or null. 5
  • 6. Visage on Android§ Visage Runs as a Native App on Android§ Full Access to all the Android APIs§ Declarative Layer on Top of Android APIs 6
  • 7. Module 1HELLO WORLD, VISAGE 7
  • 8. Exercise 1.A – Android Setup§ Setup and run the VirtualBox image§ Create an emulator instance§ Create a new Android project from the command line§ Run the project in the emulator 8
  • 9. Setting Up Your Machine1.  Copy these files off the USB stick (or from http://projavafx.com/VisageLab/): -  VirtualBox for your platform (Mac, Windows, or Linux) -  VisageLab folder1.  Decompress VisageLab/Visage Dev2.vdi.zip2.  Install VirtualBox3.  Open Visage Dev.vbox 9
  • 10. Set Up Your Device for Debugging§ And mount it from: -  Devices > USB Devices > (your-device-name) 10 10
  • 11. Or Create a Virtual Android Device§ Launch the AVD Manager by typing: android 11
  • 12. Setting Up Your Project§ Project creation command: -  android create project –t 1 –p HelloVisage –k org.test –a HelloVisage§ Arguments: -  n : Project name (optional) -  t : Target ID of the new project (required) -  p : Project directory (required) -  k : Package name for the application (required) -  a : Name of the default Activity (required) 12
  • 13. Android XML Code<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hello World, HelloVisage" /> </LinearLayout> 13
  • 14. Plus some more Java…public class HelloVisage extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedIS) { super.onCreate(savedIS); setContentView(R.layout.main); } } 14
  • 15. Run Your Project§ cd HelloVisage§ ant install§ Open it in the applications menu 15
  • 16. Exercise 1.B – All Java Conversion§ Make sure you have the basic project running first§ Convert the XML Code to Java§ Run the all Java project§ You should get identical results 16
  • 17. Converted XML Code (simplified)public class HelloVisage extends Activity { @Override public void onCreate(Bundle savedIS) { super.onCreate(savedIS); Context context = getApplicationContext(); LinearLayout layout = new LinearLayout(context); layout.setOrientation(LinearLayout.VERTICAL); TextView text = new TextView(context); text.setText("Hello World, Java Only"); layout.addView(text); setContentView(layout); }} 17
  • 18. (and here are the imports…)import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.TextView; 18
  • 19. Exercise 1.C – DDMS Debugging§ So you made a mistake in your code… the compiler can’t catch everything -  (even if you didn’t make a mistake, force one… a beautiful NullPointerException will do)§ Launch DDMS and select your emulator/device 19
  • 20. Break the code (change in bold)public class HelloVisage extends Activity { @Override public void onCreate(Bundle savedIS) { super.onCreate(savedIS); Context context = getApplicationContext(); LinearLayout layout = null;//new LinearLayout(context); layout.setOrientation(LinearLayout.VERTICAL); TextView text = new TextView(context); text.setText("Hello World, HelloVisage"); layout.addView(text); setContentView(layout); }} 20
  • 21. DDMS Displaying a Stack Trace 21
  • 22. Exercise 1.D – Visage Port§ Modify the build script to compile Visage§ Copy the Visage Runtime libraries§ Convert the Java code to Visage§ Run on device/emulator 22
  • 23. Modify the Build Script (1)<target name="-post-compile"> <path id="android.classpath"> <fileset dir="./libs" includes="*.jar" /> <path refid="android.target.classpath"/> <pathelement location="${out.classes.absolute.dir}"/> </path> <pathconvert refid="android.classpath" property="androidcpath"/> <path id="visage.sources"> <fileset dir="${source.absolute.dir}" includes="**/*.fx"/> </path> 23
  • 24. Modify the Build Script (2) <pathconvert refid="visage.sources" property="visagepath" pathsep=" "/> <exec executable="${visagehome}/bin/javafxc${binary.extension}"failonerror="true" logerror="true"> <arg value="-d"/> <arg value="${out.classes.absolute.dir}"/> <arg value="-cp"/> <arg value="${androidcpath}"/> <arg line="${visagepath}"/> </exec></target> 24
  • 25. Add Some Properties…§ local.properties: -  visagehome=/home/visage/visage-sdk -  binary.extension= 25
  • 26. Copy Over the Runtime JAR§ Copy: -  javafxrt.jar§ From: -  $visagehome/lib/shared/§ To: -  $projectdir/libs 26
  • 27. Straight JavaFX Conversion...public class Test extends Activity { override function onCreate(savedInstanceState:Bundle) { super.onCreate(savedInstanceState); def context = getApplicationContext(); def layout = new LinearLayout(context); layout.setOrientation(LinearLayout.VERTICAL); def text = new TextView(context); text.setText("Hello World, Hello Long Visage"); layout.addView(text); setContentView(layout); }} 27
  • 28. Rename your source file§ *.java -> *.fx 28
  • 29. Exercise 1.E – Simplified Visage§ Include the visage-android jar§ Modify the Visage code to use the new APIs§ Run on device/emulator 29
  • 30. Copy the visage-android JAR§ Copy: visage-android.jar§ From: /home/visage/visage-android/dist/§ To: $projectdir/libs 30
  • 31. Android JavaFX Codepublic class HelloVisage extends Activity { override var view = LinearLayout { orientation: Orientation.VERTICAL view: TextView { text: "Hello World, Beautified Visage" } }} 31
  • 32. And change the imports…§ org.visage.android.app.Activity;§ org.visage.android.widget.LinearLayout;§ org.visage.android.widget.Orientation;§ org.visage.android.widget.TextView; 32
  • 33. Working Hello Visage Application 33
  • 34. Lesson 1JAVA VS. VISAGE 34
  • 35. Language SimilaritiesJava is… Visage is…§ Statically typed § Statically typed§ Compiled to bytecodes § Compiled to bytecodes§ Runs on the JVM § Runs on the JVM§ Has a large library § Can call Java libraries 35
  • 36. Language Differences Visage • Type Inferencing • Closures • Binding • Sequences • Animation Syntax Java • Annotations • Generics • Multi-Threading 36
  • 37. Integrating Visage and Java§ Calling Java from Visage -  Can call Java interface or classes directly -  Automatic conversion to and from Arrays and Collections -  Can even extend Java interfaces and classes§ Calling Visage from Java -  Easiest way is to create a Java interface that Visage extends -  Can invoke Visage as a script and get results back 37
  • 38. Lesson 2VISAGE LANGUAGE FUNDAMENTALS 38
  • 39. Datatype Support DataType   Java Equivalent   Range   Examples   Boolean   boolean   true or false   true, false   Integer   int   -2147483648 to 2147483647   2009, 03731, 0x07d9   Number   Float   1.40×10-45 and 3.40×1038   3.14, 3e8, 1.380E-23   String   String   N/A   "javas", in"side"er   Duration   <None>   -263 to 263-1 milliseconds   1h, 5m, 30s, 500ms   Length <None> dp, sp, em, %, mm, cm, in 2mm, 5sp, 1in Angle <None> rad, deg, turn 1rad, 30deg Color <None> #RRGGBB, #RGB, #CCCCCC, #202020|D0 #RRGGBB|AA, #RGB|A Character   char   0 to 65535   0, 20, 32   Byte   byte   -128 to 127   -5, 0, 5   Short   short   -32768 to 32767   -300, 0, 521   Long   long   -263 to 263-1   2009, 03731, 0x07d9   Float   float   1.40×10-45 and 3.40×1038   3.14, 3e8, 1.380E-23   Double   double   4.94×10-324 and 1.80×10308   3.14, 3e231, 1.380E-123   39
  • 40. Visage OperatorsOperator   Meaning   Precedence   Examples  ++   Pre/post increment   1   ++i, i++  --   Pre/post decrement   1   --i, i--  not   Boolean negation   2   not (cond)  *   Multiply   3   2 * 5, 1h * 4  /   Divide   3   9 / 3, 1m / 3  mod   Modulo   3   20 mod 3  +   Add   4   0 + 2, 1m + 20s  -   Subtract (or negate)   4 (2)  -2, 32 -3, 1h -5m  >  Multiplication and division of two durations is allowed, but not meaningful>  Underflows/Overflows will fail silently, producing inaccurate results>  Divide by zero will throw a runtime exception 40
  • 41. Visage Operators (continued)Operator   Meaning   Precedence   Examples  ==   Equal   5   value1 == value2, 4 == 4  !=   Not equal   5   value1 != value2, 5 != 4  <   Lessthan   5   value1 < value2, 4 < 5  <=   Lessthanorequal   5   value1 <= value2, 5 <= 5  >   Greater than   5   value1 > value2, 6 > 5  >=   Greater than or equal   5   value1 >= value2, 6 >= 6  instanceof   Is instance of class   6   node instanceof Text  as   Typecast to class   6   node as Text  and   Boolean and   7   cond1 and cond2  or   Boolean or   8   cond1 or cond2  +=   Add and assign   9   value += 5  -=   Subtract and assign   9   value -= 3  *=   Multiply and assign   9   value *= 2  /=   Divide and assign   9   value /=4  =   Assign   9   value = 7   41
  • 42. Access ModifiersModifier   Name   Description  <default>   Script only access   Only accessible within the same script file  package   Package access   Only accessible within the same package  protected   Protected access   Only accessible within the same package or by subclasses.  public   Public access   Can be accessed anywhere.  public-read   Read access modifier   Var/def modifier to allow a variable to be read anywhere  public-init   Init access modifier   Var/def modifier to allow a variable to be initialized or read anywhere   42
  • 43. Data Binding§ A variable or a constant can be bound to an expression -  var x = bind a + b;§ The bound expression is remembered§ The dependencies of the expression is watched§ Variable is updated lazily when possible 43
  • 44. Module 2CONTROLS AND SETTINGS 44
  • 45. Exercise 2.A – NetBeans Integration§ Create a new JavaFX NetBeans project§ Merge in build scripts from Android project§ Start coding! 45
  • 46. Create a new JavaFX Project§ File > New Project…§ Name the project “ConfigReporter”§ In package "org.test" 46
  • 47. Merging Project Folders§ Copy these files over: -  *.properties -  AndroidManifest.xml -  res/ -  libs/ -  proguard.cfg -  build.xml [replace] 47
  • 48. Merging Build Scripts§ Update the build.xml file: Set the project name to “ConfigReporter”§ Update the strings.xml file: Set the app_name to “ConfigReporter”§ Load the NetBeans property files (in build.xml): <property file="nbproject/private/config.properties"/> <property file="nbproject/private/configs/${config}.properties"/> <property file="nbproject/private/private.properties"/> <property file="${user.properties.file}"/> <property file="nbproject/configs/${config}.properties"/> <property file="nbproject/project.properties"/> 48
  • 49. Alias NetBeans Targets:<target name="launch" depends="install”> <exec executable="${adb}" failonerror="true"> <arg line="${adb.device.arg}"/> <arg value="shell"/> <arg value="am"/> <arg value="start"/> <arg value="-n"/> <arg value=”org.test/.ConfigReporter"/> <arg value="-a"/> <arg value="android.intent.action.MAIN"/> </exec> </target> <target name="jar" depends="compile"/> <target name="run" depends="launch"/> 49
  • 50. Update AndroidManifest.xml§ Change project name to "ConfigReporter" 50
  • 51. Modify Project Properties§ Set JavaFX Platform to “Visage_SDK”§ Add Libraries: -  “libs” folder -  android.jar 51
  • 52. Update ConfigReporter.fx§ Make it extend the visage Activity class§ For now, you can copy the logic from HelloVisage 52
  • 53. Exercise 2.C – Android Controls§ Create a Text Field§ Create an Edit Box§ Wire them up using Binding 53
  • 54. Bound Controls (1)override var view = LinearLayout { orientation: Orientation.VERTICAL var secret:String; view: [ EditText { hint: "Super Secret Text” password: true text: bind secret with inverse 54
  • 55. Bound Controls (2) } TextView { text: "Is Revealed!!!” } TextView { text: bind secret } ]} 55
  • 56. Exercise 2.D – Button Handler§ Create a Button Control§ Add an onClick handler§ Make something happen (maybe a bind) 56
  • 57. Button onClick handlerButton { text: "Launch Settings" onClick: function() { startActivity(new Intent(this, Settings.class)); setting = "Launching..."; }}TextView { text: "Setting is:"}TextView { text: bind setting} 57
  • 58. Exercise 2.E – Android Settings§ Create a Settings Activity§ Populate it with the following preferences: -  Text -  Password -  List§ Launch it from the Button control 58
  • 59. Settings Classpublic class Settings extends PreferenceActivity { var usernamePref:EditTextPreference; var passwordPref:EditTextPreference; var pollingPref:ListPreference; override var screen = PreferenceScreen { preferences: [ … 59
  • 60. Text PreferencePreferenceCategory { title: "Preferences" preferences: [ usernamePref = EditTextPreference { title: "Username" key: "usernamePref" summary: bind if (usernamePref.text == "") "Currentlyundefined" else "Current value: {usernamePref.text}" } 60
  • 61. Password Preference passwordPref = EditTextPreference { title: "Password” key: "passwordPref” summary: bind passwordPref.text.replaceAll(".", "*");} 61
  • 62. List PreferencepollingPref = ListPreference { title: "Polling Interval" key: "pollingPref" defaultValue: "60000" entries: ["30 seconds", "1 minute", "5 minutes", "10 minutes", "15minutes", "30 minutes", "1 hour"] entryValues: ["30000", "60000", "300000", "600000", "900000","1800000", "3600000"] summary: bind pollingPref.entry} 62
  • 63. Service Metadata§ Update AndroidManifest.xml: <activity android:name=".Settings” android:label="@string/settings_label"/>§ Update string.xml: <string name="settings_label">Settings</string> 63
  • 64. Invoke the new service§ In the onClick handler: startActivity(new Intent(this, Settings.class)); 64
  • 65. Working Settings Panel 65
  • 66. Lesson 3ADVANCED JAVAFX SEQUENCES 66
  • 67. What Bind Updatesvar x = bind if(a) then b else c§ x is updated if a or b or c changesvar x = bind for (i in [a..b]) { i * i }§ Not everything is recalculated§ If a = 1 and b = 2, x is [1, 4]§ If b changes to 3, only the added element is calculated 1 4 9 67
  • 68. Binding to Expressions§ Binding to a block§ Bound block may contain any number of defs followed by one expression§ Dependencies of block is backtraced from the expression§ Binding to function invocation expression -  Regular function: dependencies are parameters -  Bound function: backtraced from final expression inside function 68
  • 69. Binding to Object Literalsvar a = 3; var b = 4;var p = bind Point { x: a, y: b };var q = bind Point { x: bind a, y: b };var r = bind Point { x: bind a, y: bind b };§ When a changes: -  p gets a new instance of Point -  q and r keep the old instance with a new x value -  r will never get a new instance of Point -  (the outer bind in r is useless) 69
  • 70. Visage Sequences§ Represents collections of homogeneous data§ A fundamental container data type§ Rich set of language facilities§ Contributor to declarative syntax§ Automatic conversion to and from Java Arrays and Collections 70
  • 71. Creating Sequences§ Explicit sequence expression -  [1, 3, 5, 7, 9]§ Elements are separated by commas§ Comma may be omitted if element ends with brace 1 3 5 7 9 71
  • 72. Creating Sequences§ Numeric sequence with range expressions: -  [1..10] 1 2 3 4 5 6 7 8 9 10§ Can have a step: -  [1..10 step 2] 1 3 5 7 9 -  [0.0..0.9 step 0.1] 0 .1 .2 .3 .4 .5 .6 .7 .8 .9§ Can be decreasing: -  [10..1 step -3] 10 7 4 1§ Beware of step that goes opposite direction: -  [10..1] is []§ Exclusive right end -  [1..<5] 1 2 3 4
  • 73. Getting Info from Sequencesints = [1, 3, 5, 7, 9] 1 3 5 7 9 [0] [1] [2] [3] [4]§ sizeof ints is 5§ ints[0] is 1, ints[1] is 3, ..., ints[4] is 9§ ints[-1] is 0 (default value of Integer), so is ints[5]§ For a sequence of objects, the default is null 73
  • 74. Getting Slices from Sequencesints = [1, 3, 5, 7, 9] 1 3 5 7 9 [0] [1] [2] [3] [4]§ ints[0..2] is [1, 3, 5]§ ints[0..<2] is [1, 3]§ ints[2..] is [5, 7, 9]§ ints[2..<] is [5, 7]§ ints[2..0], ints[-2..-1], ints[5..6] are all []s 74
  • 75. Getting Subsets from Sequencesints = [1, 3, 5, 7, 9] 1 3 5 7 9 [0] [1] [2] [3] [4]§ ints[k | k > 6] is: -  [7, 9] (k > 6 is a condition)§ ints[k | indexof k < 2] is: -  [1, 3]§ ints[k | k > 10] is: -  [] 75
  • 76. Inserting into Sequencesints = [1, 3, 5, 7, 9] 1 3 5 7 9insert 20 into ints 1 3 5 7 9 20insert 30 before ints[2] 1 3 30 5 7 9 20insert 40 after ints[4] 1 3 30 5 7 40 9 20insert [50, 60] into ints 1 3 30 5 7 40 9 20 50 60
  • 77. Deleting from Sequences§ ints = [1, 3, 5, 7, 9] 1 3 5 7 9§ delete 7 from ints 1 3 5 7 9§ delete ints[0] 1 3 5 9§ delete ints[0..1] 3 5 9§ delete ints: ints becomes [] 9
  • 78. Sequence Puzzlers What is the size of this sequence: § [1..10 step -1] What does this evaluate to: § [10..<20 step 2][k|k>17] What is the size of this sequence: § sizeof [20..1 step -3]
  • 79. How Did I Do?
  • 80. Thank You!Stephen Chinhttp://steveonjava.comTweet: @steveonjava 80