Upload
others
View
21
Download
0
Embed Size (px)
Citation preview
Introduction to the JavaFX™ Script Programming Language
Richard BairStuart MarksSun Microsystems, Inc.
2
Richard Bair and Stuart Marks are on the engineering team responsible for the JavaFX
runtime and core class libraries.
Introduction to JavaFX Script Programming
> Major focus: application programming> Minor focus: class and library programming> Not covered:
• finer points of language design• compilation• grammar and syntax• type theory
3
> Object-oriented (of course)> Expression language> Declarative and Procedural> Integrates with Java (can import Java classes)> Incorporates the concept of time
4
The JavaFX™ Script Language
A scripting language for interactive graphics, media, and animation.
The JavaFX™ Script Language
> Script-like features (type inference, loose exprs)> Convenient data binding> Functions, function variables, anonymous functions> Object model
• Classes, mixins• Instances accessed via references• References can be null...• But NullPointerException isnʼt thrown
5
The Flavor of JavaFX Script
> Has sort-of a “scripty” feel to it• Expressions at script level (outside of classes)• Need not declare all types• Object and function literals
> But...• Strongly typed• Still have compile-edit-debug cycle (for now)• Need to declare all variables
6
Hello World
> Complete source code:
println("Hello, world!");
> No imports, class declarations, main(), ....> But more complex programs will require them
7
> JavaFX Script source files are called “scripts”> Most things in JavaFX Script are expressions
• All blocks are expressions• The last line is the result
• “Statements” are also expressions• x = if (condition) then 1 else 2;
• Function return value• The last expression in function body is the result
> Scripts also contain class declarations
JavaFX Script Explained
8
Type Inference
> Neednʼt declare types if the compiler can figure them out• var x = 5; // Integer• var cond = true; // Boolean• function f() { "xyz" } // String
> Statically typed (not dynamic)• Every variable has a type, even if type not declared• Declaration: var varname:type = init-value;• var x:Integer = 5;
9
> Primitive types from Java:• Boolean, Integer, Long, String, ...
> Number> Duration> Primitives cannot be null
• Null string coerced to an empty string> Void (only as return “type” of a function)
Data Types
10
> Most of the usual suspects, some spelled differently• + - / *• ++ --• *= /= += -=• and or not• = == !=• mod
> But no bitwise operators
Operators
11
> if (booleanExpression) then a else b> if (booleanExpression) a else b> if (booleanExpression) { a } else { b }> while (booleanExpression) { ... }> for (i in sequence) { ... }
• Can get index of item “i” by “indexof i”> break, continue, return> try, catch, finally, throw
Flow Control
12
Other Language Features
> Comments: // and /* ... */> String expressions:
• println("The value of x is {x}");> Variable declarations
• Use var or def• A def variable cannot be assigned to• But def is not a constant• Can still change value if bind is used
13
Sequences
> An immutable, ordered collection of objects> Sequences are flat (they do not nest)> A sequence cannot be null (but it can be empty)> Access by index or by slice> Can insert and delete by value or by index> Single object converted into a sequence if required
• You can sometimes leave off brackets> Sequences of numbers are handled specially
14
Sequences
15
// the following are equivalentvar names:String[] = "Richard";var names:String[] = [ "Richard" ];
// no null sequences, just empty onesvar names:String[] = null;insert "Fred" into names; // works
// elements are accessed by index or slicevar names = ["Stuart", "Richard", "Jasper"];var jasper = names[2]; // Stringvar speakers = names[0..1]; // String[]
Sequence Operations
16
// Insertioninsert [ "Fred", "Jasper" ] into names; // appendsinsert "Stuart" before names[1];insert "Duke" after names[1];
// Deletiondelete "Duke" from names;delete names[0];delete names[x..y];
// Sequences are immutablevar myCopy = names;delete "Richard" from names; // myCopy is unchanged
Sequences
// sequences are flatvar a = [ 1, 2, 3 ];insert [ 4, 5, 6 ] into a;
[ 1, 2, 3, 4, 5, 6 ]
// numeric ranges stored in compact form; useful with for-loops
var b = [1..1000000000];
for (i in [-5000000..5000000]) { ... }
// range expressionsfor (j in [ 0..<10 step 2 ]) { j }
[ 0, 2, 4, 6, 8 ]
17
Sequence Selection, Reversal, For-Loop
var seq = [1..10];
println(seq[x | x mod 2 == 0]);[ 2, 4, 6, 8, 10 ]
println(reverse seq);[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
// value of a for-loop is a sequence of values from its bodyprintln(for (x in [1..5]) { x*x });
[ 1, 4, 9, 16, 25 ]
18
Classes, Mixins, and APIs
> Normal classes similar to Java classes> Mixin classes like Java interfaces
• Can include function implementations• Can include variable declarations and init values
> Extending classes• At most one normal superclass• Arbitrary number of mixin classes
19
Class and Mixin Class Examples
class A {var x;function f() { ... }
}
mixin class M {var y;function g() { ... }
}
class B extends A, M {...
}
20
Access Modifiers
> public, protected same as Java> package access must be declared explicitly> The default is now private; no “private” keyword> New modifiers for variable declarations:
• public-read• public-init
21
Functions and Function Variables
> Functions• Script level, class, or literal (anonymous)• Return value is last expression in body
> Function variables• A variable that “points to” a function• Can be assigned a function by name or a function
literal
22
Function Examples
function sum(seq:Number[]):Number {var s:Number = 0;for (n in seq) { s += n; }s
}
function foo() { println("foo"); }var myFunc = foo;myFunc = function() { println("bar"); }myFunc();
Group {onMouseMoved: function(...) { ... }content: [ ... ]
}
23
> bind is a way to tie the value of one variable to the value of an expression• the variable is automatically updated when any
value in the expression changes> Binding must be defined when the variable is
initialized• In initial declaration or in object literal
> Bound variables cannot be set manually> Triggers: code executed when a var changes
Bind and Triggers
24
Using Bind
25
public class C {public var x1:Number;public var x2:Number;
// Whenever x2 or x1 changes, distance will be updated// Binding can be used to maintain invariants
public-read var distance:Number = bind x2 - x1;}
var d:C = ... ;
d.distance = 100; // error
Bind Performs Minimal Re-evaluation
function f() { ... }function g() { ... }
var a = ... ;var b = ... ;
def x = bind f(a) + g(b)// f and g are called to compute x initially
a++;// to recompute x, f() is called but g() is not!// the return values of function calls are cached
26
Triggers
> Allow code to be executed when a variable changes value
> Variable declarations have “on replace” clause> Can access old and new values> Also supports replacement of sequence slices
27
Triggers
var a:Number on replace {println("a is now {a}");
}
var b:Number on replace oldB {println("b changed from {oldB} to {b}");
}
var seq:String[] on replace oldItems[start..end] = newItems {println("{seq[start..end]} replaced by {newitems}");
}
28
> Concise declarative syntax for object creation> Similar to JavaScript> A series of variable: initial-value pairs> The initial-value is an expression> Can be nested arbitrarily
• Useful for creating scene graph structures> Combine with bind for maximum effect
Object Literals
29
30
Object Literals
// creates a Rectanglevar rect = Rectangle {
x: 10y: 10width: 100height: 100
};rect.x = 20; // ok
// public-init variables can be initialized but not assignedvar p = Point2D {
x: 20y: 30
};p.x = 40; // error
31
Nesting Object Literals
// a Rectangle with a Color inside itvar rect = Rectangle {
x: 10y: 10width: 100height: 100fill: Color {
red: 1green: 0blue: 0
}}
32
Object Literals
// A variation that allows me to reference the color latervar color:Color; var rect = Rectangle {
x: 10 y: 10 width: 100 height: 100fill: color = Color {
red: 1green: 0blue: 0
}}
var rect2 = Rectangle {x: 200 y: 10 width: 100 height: 100fill: color
}
Bind vs Object Literals
// mutates r1.width if myWidth changesvar r1 = Rectangle {
x: 50y: 50width: bind myWidthheight: 100
}
// creates a new Rectangle, replacing r2, when myWidth changesvar r2 = bind Rectangle {
x: 50y: 50width: myWidthheight: 100
}
33
API Design Style
> No getters• Use public-read variables
> No setters• Use public variables with a trigger
> No constructors• Use public-init variables and object literals
> Fewer listeners and callbacks• Expose state variables, allow binding on them
34
Time and Duration
> New primitive type: Duration• var d = 100ms;• other units supported: 5s 1m 0.5h
> Timeline class• modifies a value over time toward a target value• supported by special language syntax
• var v = 0;• Timeline { keyFrames: at (1s) { v => 100 } }
35
Putting It All Together
> Language and runtime work together> Language
• data binding• object literals• concise syntax
> Runtime and library APIs• scene graph• time & animation
36
Putting It All Together
var rotateValue = 0.0;
Timeline { keyFrames: at (4s) { rotateValue => 360.0 } repeatCount: Timeline.INDEFINITE}.play();
Stage { scene: Scene { width: 500 height: 500 content: for (xval in [100, 200, 300], yval in [100, 200, 300]) { Rectangle { x: xval width: 50 y: yval height: 50 rotate: bind rotateValue }} } }
37
Putting It All Together – DEMO
38
Why A New Language?
39
> A programming language is not about telling the computer what to do, but instead is about expressing the programmerʼs intent.
> A programming language needs to embody new, higher-level concepts and to abstract away irrelevant detail. (Brooks 1993, HOPL-II keynote)
> Itʼs fun!
References
40
> Part 2: TS-5577 JavaFX Graphics & Animation> Many other JavaFX talks at JavaOne> JavaFX home page: javafx.com
• Tutorials, FAQ, API Documentation• Sample code• Download NetBeans + JavaFX SDK
> JavaFX Script Language Reference• https://openjfx.dev.java.net/langref/
Richard [email protected]
Stuart [email protected]