ALEXANDER CASALL
JavaFX in Action
Alexander Casall
sialcasa
HISTORY OF JAVAFX USING GOOGLE TRENDS
JavaFX Script1.0
F3
1.3
JavaFX2.0
JavaFX8
Classpath integration3DAPIPrinting
8.XAccessibility,Controls...
JavaAPIOpenJFX
ScriptLanguageFlashSuccessor
0 20 40 60 80 100 120 140 160
IneverusedJavaFXbefore
IdidsomeexperimentswithJavaFX
IuseJavaFXinaproductiveapplication
IuseJavaFX,buttheprojectisstillindevelopment
Poll:DoyouuseJavaFX?
DoyouuseJavaFX?
Jaxenter poll
38%
29%
20%
10%
Where can you use JavaFX?
Embedded (even on ARM)
TODOMobileScreenshot
Mobile
Web(Demos later)
Even for boringDesktop Apps
Office Management Software of the German AIDS Foundation
Where to start with FX?
Hello World
Stage
Scene
VBox
StackPane
Label Button
extends javafx.scene.Node
ImageView
Beyond Hello World
GridPane grid = new GridPane();grid.setHgap(10);grid.setVgap(10);
Text scenetitle = new Text("Antragsgegenstand");scenetitle.setFont(Font.font("SegoeUI", FontWeight.BOLD, 13.0));grid.add(scenetitle, 0, 0, 2, 1);
Label categoryLabel = new Label("Kategorie:");grid.add(categoryLabel, 0, 1);
ComboBox<String> categoryCombo = new ComboBox<>();grid.add(categoryCombo, 1, 1);categoryCombo.setMaxWidth(Double.MAX_VALUE);
Label subjectLabel = new Label("Gegenstand:");grid.add(subjectLabel, 0, 2);
TextField subjectTextField = new TextField();grid.add(subjectTextField, 1, 2);
Label statusLabel = new Label("Status:");grid.add(statusLabel, 0, 3);
ComboBox<String> statusCombo = new ComboBox<>();grid.add(statusCombo, 1, 3);statusCombo.setMaxWidth(Double.MAX_VALUE);
GridPane grid = new GridPane();grid.setHgap(10);grid.setVgap(10);
Text scenetitle = new Text("Antragsgegenstand");scenetitle.setFont(Font.font("SegoeUI", FontWeight.BOLD, 13.0));grid.add(scenetitle, 0, 0, 2, 1);
Label categoryLabel = new Label("Kategorie:");grid.add(categoryLabel, 0, 1);
ComboBox<String> categoryCombo = new ComboBox<>();grid.add(categoryCombo, 1, 1);
FXMLDeclaration of the UI
<GridPane fx:controller="de.aidsstiftung.aida.ContractView" …><columnConstraints>…</columnConstraints><rowConstraints>…</rowConstraints><children><TextField fx:id="subjectTextField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<ComboBox fx:id="statusCombo" onAction="#onStatusComboAction" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<ComboBox fx:id="categoryCombo" onAction="#onCategoryComboAction" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Text strokeType="OUTSIDE" styleClass="headerlabel” text="Antragsgegenstand" />
<Label text="Kategorie" GridPane.rowIndex="1" /><Label text="Gegenstand" GridPane.rowIndex="2" /><Label text="Status" GridPane.rowIndex="3" />
</children></GridPane>
public class ContractView{
@FXMLprivate TextField subjectTextField;
@FXMLprivate ComboBox<String> statusCombo;
@FXMLprivate ComboBox<String> categoryCombo;
@FXMLvoid onCategoryComboAction(ActionEvent event) {
System.out.println("Category changed: " + categoryCombo.valueProperty());}
@FXMLvoid onStatusComboAction(ActionEvent event) {
System.out.println("Status changed" + statusCombo.valueProperty());}
URL fxml = getClass().getResource("ContractView.fxml");FXMLLoader loader = new FXMLLoader(fxml);loader.setController(new ContractView());GridPane grid = loader.load();
http://gluonhq.com/products/downloads/
Use Scene Builder to create UI-Components
How many FXML Files were used?
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<StackPane xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx=…><children>
<fx:include source="child1.fxml" /><fx:include source="child2.fxml" />
</children></StackPane>
Back to our component
Coded FXML
CSSStyling
<GridPane styleClass="contentgrid"><columnConstraints>…</columnConstraints><rowConstraints>…</rowConstraints><children><TextField fx:id="subjectTextField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<ComboBox fx:id="statusCombo" onAction="#onStatusComboAction" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<ComboBox fx:id="categoryCombo" onAction="#onCategoryComboAction" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Text strokeType="OUTSIDE" styleClass="headerlabel” text="Antragsgegenstand" />
<Label text="Kategorie" GridPane.rowIndex="1" /><Label text="Gegenstand" GridPane.rowIndex="2" /><Label text="Status" GridPane.rowIndex="3" />
</children></GridPane>
.headerlabel{-fx-font-width:15pt;-fx-font-weight:bold;
}
.contentgrid{-fx-hgap: 10px;-fx-vgap: 10px;
}
.contentgrid > .combo-box{-fx-max-width: infinity;
}
SceneBuilder CSS Debugger
CSS ScopesApplication, Scene, FXML, Control
APPLICATION SCOPE
Application.setUserAgentStylesheet("file:///style.css");
NODE SCOPE
CONTROL SCOPE
public class Calendar extends Control {…@Overridepublic String getUserAgentStylesheet(){
return "calendar.css";}
}
Property API
Bindings, Listener
StringProperty
String
StringProperty
String
Binding
Observer
Property API
textfield1.textProperty().bindBidirectional(textfield2.textProperty());
ColorPicker Example
TextField searchTextField = new TextField();Button searchButton = new Button();
searchButton.disableProperty().bind(searchTextField.textProperty().isNotEmpty());
Button searchButton = new Button();TextField searchTextField = new TextField();
BooleanBinding isNumberBinding = Bindings.createBooleanBinding(() ->
searchTextField.getText().matches(".*\\d+.*"),searchTextField.textProperty());
searchButton.disableProperty().bind(searchTextField.textProperty().isNotEmpty() .and(isNumberBinding));
Fancy Stuff
Dropshadow
Effects
Animation
TIMELINES AND TRANSITIONS
0s 10s
layoutXProperty ==0 layoutXProperty ==250
KeyValue targetPoint = new KeyValue(node.translateXProperty(), 250);KeyFrame keyFrame = new KeyFrame(Duration.seconds(10), targetPoint);Timeline moveTimeline = new Timeline(keyFrame);moveTimeline.play();
TranslateTransition moveTransition = new TranslateTransition(Duration.seconds(10), node);
moveTransition.setByY(250);moveTransition.play();
More helpful Features
Multi TouchGestures and More
Pane taskPane = new TaskPane(task);
taskPane.setOnTouchMoved(new EventHandler<TouchEvent>(){@Overridepublic void handle(TouchEvent event){
calculateScaleOfTask(event.getTouchPoints());}
});
Shape
Shape
Shape
Rezizable
node.setOnSwipeRight(…);
node.setOnRotate(…);
node.setOnZoom(…);
node.setOnScroll(…);
Multi Touch and Gestures
WEBVIEWEmbed Webcontent into JavaFX Applications
Maps Example
WebView
WebEngine
Loads a Webpage
Manages DOM
Executes JavaScript
JavaScript <-> Java
Node in GraphScene
STRUCTUREWebView
System.out.println(webEngine.getUserAgent());
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/538.19 (KHTML, like Gecko) JavaFX/8.0 Safari/538.19
TYP / VERSIONWebEngine
webEngine.load("http://google");
webEngine.loadContent("<html><body>hello</body></html>");
webEngine.loadHtml("/hello.html");
LOAD CONTENTWebEngine
INTERACTION
WebView
LAST BUT NOT LEAST
Test & Deployment
Test-Pyramid
Unit Tests
Integration Tests
Acceptance Tests
TestFX
rightClickOn("#desktop").moveTo("New").clickOn("Text Document"); write("myTextfile.txt").push(ENTER); // when: drag(".file").dropTo("#trash-can"); verifyThat("#desktop", hasChildren(0, ".file"));
QF-Test
DEPLOYMENT
Webstart is an Option
Package a native app is another option
javapackager -makeall -appclass src/de/saxsys/javafx/Starter.java -name Example -width 600 -height 600
1. Package
https://github.com/edvin/fxlauncher
Launcher App.v1
2. Distribute
Über URL erreichbare Ablage
https://github.com/edvin/fxlauncher
Launcher App.v1
2. Distribute
via URL accessible Space
https://github.com/edvin/fxlauncher
Launcher App.v1
2. Distribute
App.v1
https://github.com/edvin/fxlauncher
Launcher App.v2
2. Distribute
App.v1
Break :-)
JavaFX runs on mobile using
JavaFX runs also in the browser using
Hello World
controller and model tier (business logic)
Server
JavaFX (JAVA, FXML, CSS)
JVM
Client
HTML5 (CSS, JS, SVG)
view tier (rendering)
Browser
Architecture
JavaVirtualMachine
JDKAPILibraries&Tools
Java2D/OpenGL/D3D
Prism/GlassWindowingToolkit/MediaEngine/WebEngine
QuantumToolkit
JavaFXPublicAPIsandSceneGraph
How does the magic works
JavaVirtualMachine
JDKAPILibraries&Tools
Java2D/OpenGL/D3D
Prism/GlassWindowingToolkit/MediaEngine/WebEngine
QuantumToolkit
JavaFXPublicAPIsandSceneGraph
How does the magic works
● Reasonablenewbrowser● Websocket supported● JavaScriptenabled● Usage of Webspecific APIs
Prerequisites
Multiview Demo
http://multiview.jpro.io
jpro.io
Let‘s answer the question:Who uses JavaFX?