building data rich interfaces with javafx
DESCRIPTION
Presentation on Data Rich Interfaces in JavaFX given at Jazoon 2010.TRANSCRIPT
SPEAKER‘S COMPANY
LOGO
Building Data Rich Interfaces with JavaFXStephen ChinInovis
SPEAKER‘S COMPANY
LOGO
About the Presenter
Director SWE Inovis, Inc.MBA
Belotti Award
Uber ScrumMaster
XP Coach
Agile Portfolio Process Speaker
Open-Source JavaFX HackerPro JavaFX Author
Java Champion
JavaOne Rockstar
JFXtras
WidgetFX
FEST-JavaFX
Silicon Valley JavaFX User Group Founder
Motorcyclist
Family Man
SPEAKER‘S COMPANY
LOGO
3
AGENDA
> JavaFX Technology Stack> Data Binding> JavaFX 1.3 Controls> Control Styling> JavaFX 1.3 Layouts> Web Service Integration> JFXtras Data-driven Controls> Apropos Demo> Pro JavaFX Quiz with Prizes!
SPEAKER‘S COMPANY
LOGO
JavaFX Technology Stack
JFXtras Project
XControls Swing HandlersXLayouts Wipe
Java Platform
JVM Security APIs Deployment …
JavaFX Platform
Controls Layouts Media Web ServicesBinding CSS
SPEAKER‘S COMPANY
LOGO
Evolution of Data Binding
JavaFX BindingBind LibraryProperty Change ListenersCallbacks
SPEAKER‘S COMPANY
LOGO
Bind Expressions
> Unidirectional:
property: bind object.value
property: bind sequence[index]
sequence: bind for (v in values) convert(v)
> Bijective:
property: bind value with inverse
> Function:
public bound function calculateTotal(subtotal, tax) { return subtotal * (1 + tax);}
New in JavaFX 1.3 – All binding is lazy!
SPEAKER‘S COMPANY
LOGO
Binding to Controls
bound function getScore() {[
ScoreLine {line: "Ski Jumping - Individual Norml"}
ScoreLine {line: " "}
ScoreLine {line: bind " {%-10s medal.type} "}
ScoreLine {line: bind "{%-17s medal.name} {%-3s medal.country} {%3.1f medal.score}"}
]}
def sb = ScoreBoard {
lightColor: bind medal.lightColor
lines: bind getScore()
onMousePressed: function(e) {
if (e.primaryButtonDown) {
medal = medals[(Sequences.indexOf(medals, medal) + 1) mod sizeof medals]
} else {
FX.exit();
}}}
SPEAKER‘S COMPANY
LOGO
8
Dynamic Binding
JFXtras extension for runtime binding to an existing JavaFX object via reflection.
Example:
class ReflectionTarget {
public var fieldA:String;
}
def reflectionTarget = ReflectionTarget {fieldA: “A"}
def mirror = context.mirrorOf(reflectionTarget);
def xbind = XBind.bindWithInverse(mirror, mirror.getType().getVariable("fieldA"));
xbind.ref = "B";
What is the value of: reflectionTarget.fieldA?
SPEAKER‘S COMPANY
LOGO
Java to JavaFX Binding
Prototype by Johannes Schneider: http://blog.cedarsoft.com/
Java to JavaFX
PropertyChangeEvents: Just make your Java Bean fire PropertyChangeEvents whenever a property has changed
JavaFX to Java
Variable Setter: The corresponding setter of your Java object is called
PropertyChangeEvents: JavaFX binding updates trigger PropertyChangeEvents
JavaFxBridge.bridge(javaModel).to(slider as FXObject).connecting( JavaFxBridge.bind("amount").to("value").withInverse());
Will be included in the JFXtras 0.8 Release – Feedback on the syntax welcome!
SPEAKER‘S COMPANY
LOGO
10
JavaFX 1.3 Top 10 Features
SPEAKER‘S COMPANY
LOGO
11
JavaFX 1.3 Top 10 4 Features
1.New Controls
2.Layout Enhancements
4.Enhanced CSS
10.Preview FeaturesTOP SECRET
SPEAKER‘S COMPANY
LOGO
New Controls in JavaFX 1.3
var list = ["apples", "bananas", "oranges", "pears", "cabbage"];
ScrollView {
width: 250
height: 250
managed: false
node: VBox {
padding: Insets {top: 10, left: 10, bottom: 10, right: 10}
spacing: 10
content: [
PasswordBox {promptText: "enter password"}
Separator {}
ChoiceBox {
items: list
}
ListView {
vertical: false
items: list
}
]}}
ChoiceBox
PasswordBox
Horizontal List
Separator
ScrollView
SPEAKER‘S COMPANY
LOGO
Preview Controls in JavaFX 1.3
MenuBar {
menus: for (i in [0..4]) Menu {
text: "Menu {i}"
items: for (j in [0..4]) MenuItem {
text: "Menu Item {j}"
}
}
}
ToolBar {
items: for (i in [0..4]) Button {text: "Button {i}"}
}
TreeView {
root: TreeItem {
expanded: true
data: "Root"
children: for (i in [0..4]) [
TreeItem {
data: "Item {i}"
}]}}
MenuBar
TreeView
ToolBar
Menu
SPEAKER‘S COMPANY
LOGO
14
Styling Controls
VBox {
spacing: 20
nodeHPos: HPos.CENTER
content: [
Text {content: "Default Styling"}
Button {text: "Button"}
CheckBox {text: "CheckBox", selected: true}
Slider {value: 50}
]
layoutInfo: LayoutInfo {
margin: Insets {bottom: 20, top: 20, left: 20, right: 20}
}
}
Source: Dean Iverson, http://pleasingsoftware.blogspot.com/2010/04/so-whats-it-all-good-for.html
SPEAKER‘S COMPANY
LOGO
15
Styling Controls – Button/CheckBox
.button {
-fx-base: dodgerblue;
-fx-shape: "M 50,30 m 0,25 a 1,1 0 "
"0,0 0,-50 a 1,1 0 1,0 0,50";
-fx-scale-shape: false;
}
.check-box:selected *.label {
-fx-text-fill: red
}
.check-box:selected *.mark {
-fx-background-color: red;
-fx-shape: "M 0,0 H1 L 4,4 7,0 H8 V1 L 5,4 8,7 "
"V8 H7 L 4,5 1,8 H0 V7 L 3,4 0,1 Z";
}
Source: Dean Iverson, http://pleasingsoftware.blogspot.com/2010/04/so-whats-it-all-good-for.html
SPEAKER‘S COMPANY
LOGO
16
Styling Controls – Slider
.slider *.track {
-fx-base: derive( goldenrod, 50% );
}
.slider *.thumb {
-fx-shape: "M 50,5 L 37,40 5,40 30,60 20,95 "
"50,75 80,95 70,60 95,40 63,40 Z";
-fx-background-color: derive(goldenrod,-50%), goldenrod;
-fx-background-radius: 0, 0;
-fx-background-insets: 0, 2;
-fx-padding: 10;
-fx-effect: dropshadow( two-pass-box , rgba(0,0,0,0.6) , 4, 0.0 , 0 , 1 );
}
Source: Dean Iverson, http://pleasingsoftware.blogspot.com/2010/04/so-whats-it-all-good-for.html
SPEAKER‘S COMPANY
LOGO
17
JavaFX 1.3 Layout Enhancements
GridLayout
> Based on the JFXtras XGrid
> In the JavaFX Preview Package
Fill
> Controls how Nodes expand to take available space
Grow/Shrink
> Controls how available space is allocated between competing Nodes
> Priority values:– NEVER– SOMETIMES– ALWAYS
SPEAKER‘S COMPANY
LOGO
18
JavaFX 1.3 Layouts – Grid Grow/Fill Example
?
SPEAKER‘S COMPANY
LOGO
JUG Prize Spinner
WEB SERVICE INTEGRATION
SPEAKER‘S COMPANY
LOGO
Calling a REST Service
REST URL:
http://api.meetup.com/rsvps.json/event_id={eventId}&key={apiKey}
Output:
{ "results": [
{"zip":"94044","lon":"-122.48999786376953","photo_url":"http:\/\/photos1.meetupstatic.com\/photos\/member\/1\/4\/b\/a\/member_5333306.jpeg","response":"no","name":"Andres Almiray","comment":"Can't make it :-("}
]}
SPEAKER‘S COMPANY
LOGO
JUG Prize Spinner - JSONHandler in 3 Stepspublic class Member {
public var place:Integer;
public var photoUrl:String;
public var name:String;
public var comment:String;
}
var memberParser:JSONHandler = JSONHandler {
rootClass: "org.jfxtras.jugspinner.data.MemberSearch “
onDone: function(obj, isSequence): Void {
members = (obj as MemberSearch).results;
}}
req = HttpRequest {
location: rsvpQuery
onInput: function(is: java.io.InputStream) {
memberParser.parse(is);
}}
1POJfxO
2JSONHandler
3HttpRequest
SPEAKER‘S COMPANY
LOGO
22
ADVANCED CONTROLSJFXtras XTable and XShelf
SPEAKER‘S COMPANY
LOGO
XShelfView
High Performance
Features:
> Scrollbar
> Image Title
> Reflection Effect
> Aspect Ratio
> Infinite Repeat
Integrates With JFXtras Data Providers
Automatically Updates on Model Changes
SPEAKER‘S COMPANY
LOGO
JFXtras Data Providers
DataProvider
ObjectDataProvider SequenceObject-DataProvider
ParallelSequence-DataProvider
SequenceData-Provider
MapDataProvider
SPEAKER‘S COMPANY
LOGO
XTableView
Insanely Scalable
> Up to 16 million rows
Extreme Performance
> Pools rendered nodes
> Caches images
> Optimized scene graph
Features:
> Drag-and-Drop Column Reordering
> Dynamic Updating from Model
> Automatically Populates Column Headers
> Fully Styleable via CSS
SPEAKER‘S COMPANY
LOGO
26
XTableView Example – JUG Prize Spinner
def winnerTable = XTableView {
rowType: Member {}.getJFXClass();
rows: bind winners
columns: columns // optional
rowHeight: 50 // optional
}
columns = [
XTableColumn {
displayName: "#"
id: "place"
prefWidth: 10
renderer: TextRenderer {}
}
XTableColumn {
displayName: "Photo"
id: "photoUrl"
prefWidth: 30
renderer: ImageRenderer {
missing: placeholder
placeholder: placeholder
}
}
XTableColumn {
displayName: "Name"
id: "name"
prefWidth: 300
renderer: TextRenderer {}
}]
SPEAKER‘S COMPANY
LOGO
27
APROPOSAgile Project Portfolio Scheduler
SPEAKER‘S COMPANY
LOGO
Product Management
Sales Marketing
Operations
SupportProfessional
Services
Launch Cycle Time > Dev Cycle Time
Feature selling becomes impossible (Sales Enablement)
Melting Change Managers: 50 changes once a month to 900 changes constantly
Supported Release proliferation
Innovator’s Dilemma
…in the weeds… Development
Source: Based on Gat et al, Reformulating the Product Delivery Process, LSSC Conference, April 2010
The Agile Challenge in End-to-End Context
Source: Based on Gat et al, Reformulating the Product Delivery Process, LSSC Conference, April 2010
SPEAKER‘S COMPANY
LOGO
Product Management
Sales Marketing
Operations
SupportProfessional
Services
Development
Source: Based on Gat et al, Reformulating the Product Delivery Process, LSSC Conference, April 2010
The Three Loops of Software Governance
Internal Technical Debt Loop
External Technical Debt Loop
EnabledAdoptedValidated
Validated
Backlogged Scheduled In Process Deployed
Proposed
EnabledAdopted
1. Dev: Technical debt2. Operations/Support3. Marketing/Sales
Bottleneck
SPEAKER‘S COMPANY
LOGO
Apropos Demo
SPEAKER‘S COMPANY
LOGO
31
Pro JavaFX 1.3 Quiz
> All Binding in JavaFX is ____– Answer: Lazy
> The New Controls in JavaFX 1.3 Are: ____, ____, and ____– Answer: ChoiceBox, PasswordBox, ScrollView, Separator– Or preview: Menu, Tree, Toolbar
> The JavaFX Preview Grid was contributed by the _____ project– Answer: JFXtras
SPEAKER‘S COMPANY
LOGO
Stephen Chin http://steveonjava.com/
Inovis [email protected]
tweet: @steveonjava
SPEAKER‘S COMPANY
LOGO
33
Apropos – Portfolio View
SPEAKER‘S COMPANY
LOGO
34
Apropos – Scope View
SPEAKER‘S COMPANY
LOGO
35
Apropos – Resource View
SPEAKER‘S COMPANY
LOGO
36
Apropos – Analyze View
SPEAKER‘S COMPANY
LOGO
37
Apropos – Roadmap View