JavaFX Tutorial
Tom Schindl <[Link]@[Link]>
Montag, 28. Oktober 13
About Me
‣ CTO [Link] Systemhaus GmbH
‣ Eclipse Committer
‣ e4
‣ Platform
‣ EMF
‣ Project lead
‣ e(fx)clipse
Montag, 28. Oktober 13
Anatomy of an FX-App
Montag, 28. Oktober 13
Anatomy of an FX-App
import [Link];
public class Main extends Application {
Dervived from
base class
@Override
public void start(Stage primaryStage) {
Montag, 28. Oktober 13
Anatomy of an FX-App
import [Link];
public class Main extends Application {
Dervived from
base class
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane(); Root-Container
Montag, 28. Oktober 13
Anatomy of an FX-App
import [Link];
public class Main extends Application {
Dervived from
base class
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane(); Root-Container
Scene scene = new Scene(root,400,400); Scene with size
Montag, 28. Oktober 13
Anatomy of an FX-App
import [Link];
public class Main extends Application {
Dervived from
base class
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane(); Root-Container
Scene scene = new Scene(root,400,400); Scene with size
[Link](scene);
[Link](); Display
Montag, 28. Oktober 13
Anatomy of an FX-App
import [Link];
public class Main extends Application {
Dervived from
base class
@Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane(); Root-Container
Scene scene = new Scene(root,400,400); Scene with size
[Link](scene);
[Link](); Display
public static void main(String[] args) {
launch(args); inherited method
}
Montag, 28. Oktober 13
Lab HelloWorld
‣ Setting up Eclipse
‣ Creating your first JavaFX project
‣ Attaching the first Event-Listener
Montag, 28. Oktober 13
Lab Hello World
‣ Create a directory named „fx_tutorial“ on your filesystem
e.g. C:\fx_tutorial, /Users/tom/fx_tutorial
‣ Move eclipse-SDK-4.3.0-$arch$.[Link]/.zip to the directory
and uncompress it there
‣ Install JDK8u112
‣ Linux: extract it next to your eclipse-SDK
‣ Launch Eclipse with JDK8
‣ Linux: Launch with ./eclipse -vm ../jdk8..../bin/java
‣ Check that JDK8 is used via About > Installation
Details > Configuration - search for „[Link]“
Montag, 28. Oktober 13
Lab Hello World
‣ File > New > Project ...
‣ Search for the JavaFX category
‣ Select „JavaFX Project“ > Next
‣ Enter the following data:
‣ Project name: MyFirstProject
‣ Use an execution environment JRE: JavaSE-1.8
‣ Select: Finish
Montag, 28. Oktober 13
Lab Hello World
Montag, 28. Oktober 13
Lab Hello World
‣ Create an instance of [Link] which displays
a text „Hello World!“
‣ Handle a button click and print „Hello World!“
‣ Try to use the setOnAction API
‣ Try to use the addEventHandler API
‣ Display the button in the center of the BorderPane
Montag, 28. Oktober 13
Lab Hello World
BorderPane root = new BorderPane();
Button b = new Button("Hello World");
[Link](new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
[Link]("Hello World via setOnAction!");
}
});
[Link]([Link], new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
[Link]("Hello World via addEventHandler!");
}
});
[Link](b);
Montag, 28. Oktober 13
FX-Properties
Montag, 28. Oktober 13
FX-Properties
‣ JavaFX Beans use extend the JavaBean pattern
‣ get$Name$/set$Name$ method
‣ $name$Property method
‣ property-method returns
‣ read/writable: [Link]
‣ readonly: [Link]
‣ Property-Objects are observable and can be bound together
Montag, 28. Oktober 13
FX-Properties
public class JavaBean {
private String name;
private PropertyChangeSupport support = new PropertyChangeSupport(this);
public void setName(String name) {
[Link]("name", [Link], [Link] = name);
}
public String getName() {
return [Link];
}
}
Montag, 28. Oktober 13
FX-Properties
public class JavaFXBean {
private StringProperty name = new SimpleStringProperty(this,"name");
public void setName(String name) {
[Link](name);
}
public String getName() {
return [Link]();
}
public StringProperty nameProperty() {
return [Link];
}
}
Montag, 28. Oktober 13
FX-Properties
‣ Properties can be bound
‣ Unidirectional: Property#bind()
‣ Bidirectional: Property#bindBidirectional()
‣ Unlink bindings:
‣ Unidirectional: Property#unbind()
‣ Bidirectional: Property#unbindBirectional()
Montag, 28. Oktober 13
Lab FXProperties
‣ Create JavaFX Bean
‣ Create UI with and bind properties
Montag, 28. Oktober 13
Lab FXProperties
‣ Create a new JavaFX-Project
‣ Create a JavaFX Bean
‣ Name: MyBean
‣ Properties: String-Property named „text“
‣ Add the following UI-Elements to the Main class
‣ top: [Link]
‣ center: [Link]
‣ left: [Link] (hint: orientation!)
‣ right: [Link]
Montag, 28. Oktober 13
Lab FXProperties
‣ Make the slider accept values in range min=1 & max=10
‣ Create an instance of MyBean
‣ Bind:
‣ bidirectional: MyBean#text to TextField#text
‣ unidirectional:
‣ MyBean#text to Text#text
‣ H-Slider#value to Text#scaleX
‣ V-Slider#value to Text#scaleY
Montag, 28. Oktober 13
Lab FXProperties (for the fast one)
‣ Make sure the sliders are only modifiable when the text
field has a value entered
Montag, 28. Oktober 13
FX-Layouts
Montag, 28. Oktober 13
FX Layouts
‣ JavaFX comes with predefined layout panes like
‣ [Link]
‣ [Link]
‣ [Link]
‣ [Link]
‣ Layout constraints are applied through constant setters
BorderPane root = new BorderPane();
Button child = new Button("Layout Test");
[Link](child, Pos.CENTER_LEFT);
[Link](child);
Montag, 28. Oktober 13
FX Layouts
‣ Additional layouts
‣ SWT-Layouts part of e(fx)clipse
‣ [Link]
‣ [Link]
‣ [Link]
‣ MigPane ([Link]
Montag, 28. Oktober 13
FXML
Montag, 28. Oktober 13
FXML
‣ FXML is a declarative way to define a JavaFX-Scenegraph
‣ WYSIWYG Tool called SceneBuilder
‣ Rules how to map Java to XML-Constructors
‣ classes get xml-elements
Java: Button b = new Button()
FXML: <Button>
‣ simple attribute types get xml-attributes
Java: [Link]("Hello World");
FXML: <Button text="Hello World"
‣ complex attribute types get xml-elements
Java: new BorderPane().setCenter(new Button("Hello World"))
FXML: <BorderPane><center><Button text="Hello World" /></center></BorderPane>
Montag, 28. Oktober 13
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link]?> import [Link];
<?import [Link]?> import [Link];
<HBox xmlns:fx="[Link] HBox box = new HBox();
<children>
<Button Button button = new Button("Hello World");
text="Hello World">
</Button> [Link]().add(button);
</children>
</HBox>
Montag, 28. Oktober 13
FXML
‣ Executing actions
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<HBox xmlns:fx="[Link]
fx:controller="[Link]">
<children>
<Button
fx:id="mybutton"
text="Hello World"
onAction="#run">
</Button>
</children>
</HBox>
Montag, 28. Oktober 13
FXML
‣ Executing actions
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<HBox xmlns:fx="[Link]
fx:controller="[Link]"> Java-Class
<children>
<Button
fx:id="mybutton"
text="Hello World"
onAction="#run">
</Button>
</children>
</HBox>
Montag, 28. Oktober 13
FXML
‣ Executing actions
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<HBox xmlns:fx="[Link]
fx:controller="[Link]"> Java-Class
<children>
<Button
fx:id="mybutton" Field in class
text="Hello World"
onAction="#run">
</Button>
</children>
</HBox>
Montag, 28. Oktober 13
FXML
‣ Executing actions
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<HBox xmlns:fx="[Link]
fx:controller="[Link]"> Java-Class
<children>
<Button
fx:id="mybutton" Field in class
text="Hello World"
onAction="#run">
</Button>
Method in class
</children>
</HBox>
Montag, 28. Oktober 13
FXML
‣ Executing actions / accessing stuff in Java
<?xml version="1.0" encoding="UTF-8"?>
package application;
<?import [Link]?>
import [Link];
<?import [Link]?>
import [Link];
<?import [Link]?>
public class SampleController {
<HBox xmlns:fx="[Link]
@FXML Button mybutton;
fx:controller="[Link]">
<children>
@FXML
<Button
public void run() {
fx:id="mybutton"
text="Hello World"
}
onAction="#run">
}
</Button>
</children>
</HBox>
Montag, 28. Oktober 13
FXML
‣ layout-constraint support
‣ simple constraints: <Button [Link]="CENTER_LEFT">
‣ complex constraints: <[Link]><Insets le!="10"></Insets></
[Link]>
‣ i18n support
‣ prefix value with %: <Button fx:id="mybutton" text="%[Link]">
‣ preview: <?scenebuilder-preview-i18n-resource [Link]?>
‣ media resource support
‣ prefix value with @: <Image url="@Money-icon_48.png" />
‣ loading FXML-Files using [Link]
Montag, 28. Oktober 13
Lab FXML
‣ Create FXML
‣ Connect to controller
‣ Use i18n
Montag, 28. Oktober 13
Lab FXML
‣ Create a JavaFX-Project named „FXMLProject“
‣ Navigate to the last page in the wizard
‣ Language: FXML
‣ Root-Type: [Link]
‣ Filename: Sample
‣ Controller Name: SampleController
‣ Open Preview using Window > Show View > JavaFX > JavaFX
Preview
Montag, 28. Oktober 13
Lab FXML
‣ Create basic UI
‣ Create a center-element below the BorderPane
‣ Add a button-element with a text „Hello World“
‣ Align the button to CENTER_LEFT
‣ Open the SampleController
‣ Go back to the [Link]
‣ Add an onAction-Attribute and set #run as the value
‣ Notice the error marker
‣ Use auto-correction CTRL/CMD+1
‣ Select first proposal and notice SampleController
change
Montag, 28. Oktober 13
Lab FXML
‣ Add an fx:id to Button-element and use value mybutton
‣ Notice warning marker
‣ Use auto-correction CTRL/CMD+1
‣ Select first proposal and notice SampleController change
‣ Modify SampleController#run to update the text-Value of the
button
‣ Create a [Link]-File
‣ Add a key „[Link]“
‣ Update the FXML to use [Link]
‣ Update the Main-Code to use [Link](URL,ResourceBundle)
Montag, 28. Oktober 13
Lab FXML (for the fast ones)
‣ Try to add an image to the button
‣ Hints: graphic, ImageView, Image
‣ Hints 2: FXML-Editor does not know about url-Property
of Image
Montag, 28. Oktober 13
FXGraph
Montag, 28. Oktober 13
FXGraph
‣ FXGraph is a declarative language with a similar notation
to JSON
‣ Remove a lot of noise created by XML
‣ It „compiles“ to FXML (=no extra runtime libs needed)
‣ Has some extra features
‣ Definitions:
‣ Object-Def: Button { }
‣ Simple-Attribute: Button { text : "Hello World" }
‣ Complex-Attribute: BorderPane { center : Button { text : "Hello World" } }
Montag, 28. Oktober 13
FXGraph
package application
import [Link]
import [Link]
import [Link]
component Sample resourcefile "[Link]" controlledby SampleController {
BorderPane {
center : Button {
text : "Hello World"
}
}
}
Montag, 28. Oktober 13
FXGraph
package application
import [Link]
import [Link]
import [Link]
component Sample resourcefile "[Link]" controlledby SampleController {
BorderPane {
center : Button {
text : "Hello World"
}
} Filename
}
Montag, 28. Oktober 13
FXGraph
package application
import [Link]
import [Link]
import [Link]
component Sample resourcefile "[Link]" controlledby SampleController {
BorderPane {
center : Button {
text : "Hello World" Translations
}
} Filename
}
Montag, 28. Oktober 13
FXGraph
package application
import [Link]
import [Link]
import [Link]
component Sample resourcefile "[Link]" controlledby SampleController {
BorderPane {
center : Button {
text : "Hello World" Translations
}
} Filename Controller
}
Montag, 28. Oktober 13
FXGraph
‣ Layout-constraint support:
‣ simple constraints: Button { static alignment : "CENTER_LEFT" }
‣ complex constraints: Button { static margin : Insets { le! : 10 } }
‣ i18n support
‣ prefix string with rstring: Button { text : rstring "[Link]" }
‣ media support:
‣ prefix string with location: Image { url : location "Money-icon_48.png" }
‣ preview marker:
‣ prefix an attribute with preview: TextField { preview text : "Preview
only"}
Montag, 28. Oktober 13
FXGraph
‣ Executing actions / accessing stuff in Java
component Sample controlledby [Link] {
BorderPane {
center : Button id mybutton {
text : "Hello World",
onAction : controllermethod run
}
}
}
Montag, 28. Oktober 13
FXGraph
‣ Executing actions / accessing stuff in Java
component Sample controlledby [Link] {
BorderPane {
center : Button id mybutton {
text : "Hello World",
onAction : controllermethod run
}
}
}
Field in class
Montag, 28. Oktober 13
FXGraph
‣ Executing actions / accessing stuff in Java
component Sample controlledby [Link] {
BorderPane {
center : Button id mybutton {
text : "Hello World",
onAction : controllermethod run
}
}
}
Field in class Method in class
Montag, 28. Oktober 13
Lab FXGraph
‣ Create complex UI
‣ Connect to controller
‣ Use i18n
Montag, 28. Oktober 13
Lab FXGraph
‣ Create a JavaFX-Project named „FXGraphProject“
‣ Navigate to the last page in the wizard
‣ Language: FXGraph
‣ Root-Type: [Link]
‣ Filename: Currency
‣ Controller Name: CurrencyController
Montag, 28. Oktober 13
Lab FXGraph
‣ Create the UI
Montag, 28. Oktober 13
Lab FXGraph
‣ Put another [Link] in the left-Property
‣ put a [Link] in the center
‣ put a [Link] in the bottom
‣ add 2 [Link] as the children
‣ Put [Link] in the center Property
(Hint row, colum-index and hgrow can be set using static)
‣ add a [Link] (text=Name)
‣ add a [Link]
‣ add a [Link] (text=Abbreviation)
‣ add a [Link]
Montag, 28. Oktober 13
Lab FXGraph
‣ Create a file [Link]
‣ Add the following keys with translations:
[Link]
[Link]
[Link]
[Link]
‣ Modify [Link] adding resourcefile "[Link]" in the
component definition
‣ Use rstring in the Button and Label text-property
‣ Connect the following to the controller (using id)
‣ ListView as currencyList
‣ TextField as nameField, abbreviationField
Montag, 28. Oktober 13
Lab FXGraph
‣ Connect the buttons onAction-Slot to the controller (using
controllermethod)
‣ Add Button to addCurrency
‣ Remove Button to removeCurrency
‣ Set the id-attribute(!!!) of the GridPane to
„currencyDetail“
Montag, 28. Oktober 13
CSS
Montag, 28. Oktober 13
CSS
‣ JavaFX uses CSS to theme ALL elements
‣ Selectors supported are mainly CSS2 compatible
‣ Element-Selectors: Applies to the classname in the
SceneGraph (e.g. BorderPane, HBox, ...)
‣ ID-Selectors: Applies to the id-attribute set via Node#id:
String
‣ Class-Selectors: Applies to the classes assigned through
Node#styleClass: ObservableList<String>
Montag, 28. Oktober 13
CSS
‣ JavaFX-Controls automatically assign the controls name to
the Skin-Class making up the control. e.g. Button styles
itself not with Button but .button
Montag, 28. Oktober 13
CSS
‣ JavaFX-Controls automatically assign the controls name to
the Skin-Class making up the control. e.g. Button styles
itself not with Button but .button
SceneGraph
BorderPane
TitledPane
Montag, 28. Oktober 13
CSS
‣ JavaFX-Controls automatically assign the controls name to
the Skin-Class making up the control. e.g. Button styles
itself not with Button but .button
SceneGraph
BorderPane
TitledPane
StackPane
HBox
Label
StackPane
StackPane
Montag, 28. Oktober 13
CSS
‣ JavaFX-Controls automatically assign the controls name to
the Skin-Class making up the control. e.g. Button styles
itself not with Button but .button
SceneGraph
BorderPane logical scenegraph
TitledPane
StackPane
HBox
Label
StackPane
StackPane
Montag, 28. Oktober 13
CSS
‣ JavaFX-Controls automatically assign the controls name to
the Skin-Class making up the control. e.g. Button styles
itself not with Button but .button
SceneGraph
BorderPane logical scenegraph
TitledPane
StackPane
HBox
Label full scenegraph
StackPane
StackPane
Montag, 28. Oktober 13
CSS
‣ JavaFX properties all start with -fx
‣ Informations which properties apply to which element are
available from [Link]
scene/doc-files/[Link]
‣ e(fx)clipse CSS-Editor knows which properties apply if you
use the predefined class and element selectors
Montag, 28. Oktober 13
Lab CSS
‣ Use some simple css
Montag, 28. Oktober 13
Lab CSS
‣ Open the [Link] in the FXGraphProject
‣ Redefine the hgap / vgap for GripPanes
‣ Redefine the padding for the GridPane with ID currencyDetail
Montag, 28. Oktober 13
Working with Views
Montag, 28. Oktober 13
Working with Views
Montag, 28. Oktober 13
Working with Views
‣ All views are virtual (cells are reused!!)
Montag, 28. Oktober 13
Working with Views
‣ All views are virtual (cells are reused!!)
‣ All views are made up of Cell-Nodes
Montag, 28. Oktober 13
Working with Views
‣ All views are virtual (cells are reused!!)
‣ All views are made up of Cell-Nodes
‣ Cell-Nodes are created through factories
Montag, 28. Oktober 13
Working with Views
‣ All views are virtual (cells are reused!!)
‣ All views are made up of Cell-Nodes
‣ Cell-Nodes are created through factories
ListView<Currency> currencyList = new ListView<>();
[Link](new Callback<ListView<Currency>, ListCell<Currency>>() {
@Override
public ListCell<Currency> call(ListView<Currency> param) {
return new CurrencyCell();
}
});
Montag, 28. Oktober 13
Working with Views
‣ All views are virtual (cells are reused!!)
‣ All views are made up of Cell-Nodes
‣ Cell-Nodes are created through factories
ListView<Currency> currencyList = new ListView<>();
JDK7-Style
[Link](new Callback<ListView<Currency>, ListCell<Currency>>() {
@Override
public ListCell<Currency> call(ListView<Currency> param) {
return new CurrencyCell();
}
});
Montag, 28. Oktober 13
Working with Views
‣ All views are virtual (cells are reused!!)
‣ All views are made up of Cell-Nodes
‣ Cell-Nodes are created through factories
ListView<Currency> currencyList = new ListView<>();
JDK7-Style
[Link](new Callback<ListView<Currency>, ListCell<Currency>>() {
@Override
public ListCell<Currency> call(ListView<Currency> param) {
return new CurrencyCell();
}
});
ListView<Currency> currencyList = new ListView<>();
[Link]((param) -> new CurrencyCell());
Montag, 28. Oktober 13
Working with Views
Montag, 28. Oktober 13
Working with Views
‣ Input for views is an ObservableList
Montag, 28. Oktober 13
Working with Views
‣ Input for views is an ObservableList
‣ ListCell can be subclass and updateItem is called when a new
item is associated with the Cell (can happen at ANY time!)
Montag, 28. Oktober 13
Working with Views
‣ Input for views is an ObservableList
‣ ListCell can be subclass and updateItem is called when a new
item is associated with the Cell (can happen at ANY time!)
public class CurrencyCell extends ListCell<Currency> {
@Override
protected void updateItem(Currency item, boolean empty) {
if( item != null && ! empty ) {
setText([Link]());
} else {
setText(null);
}
[Link](item, empty);
}
}
Montag, 28. Oktober 13
Lab Views
‣ Setup the ListView
Montag, 28. Oktober 13
Lab Views
Montag, 28. Oktober 13
Lab Views
‣ Create a lib-Dir and copy there all jars from the fxgraph-
libraries
Montag, 28. Oktober 13
Lab Views
‣ Create a lib-Dir and copy there all jars from the fxgraph-
libraries
‣ Open the CurrencyController
Montag, 28. Oktober 13
Lab Views
‣ Create a lib-Dir and copy there all jars from the fxgraph-
libraries
‣ Open the CurrencyController
‣ make the ListView hold items of type Currency
Montag, 28. Oktober 13
Lab Views
‣ Create a lib-Dir and copy there all jars from the fxgraph-
libraries
‣ Open the CurrencyController
‣ make the ListView hold items of type Currency
‣ make the controller implement Initializable
Montag, 28. Oktober 13
Lab Views
‣ Create a lib-Dir and copy there all jars from the fxgraph-
libraries
‣ Open the CurrencyController
‣ make the ListView hold items of type Currency
‣ make the controller implement Initializable
‣ Add a subclass of ListCell named CurrencyCell as an inner-
static-class
Montag, 28. Oktober 13
Lab Views
‣ Create a lib-Dir and copy there all jars from the fxgraph-
libraries
‣ Open the CurrencyController
‣ make the ListView hold items of type Currency
‣ make the controller implement Initializable
‣ Add a subclass of ListCell named CurrencyCell as an inner-
static-class
‣ In the initialize-method setup the cellFactory
Montag, 28. Oktober 13
Eclipse Databinding
Montag, 28. Oktober 13
Eclipse Databinding
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
‣ single value: IValueProperty
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
‣ single value: IValueProperty
‣ list value: IListValueProperty
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
‣ single value: IValueProperty
‣ list value: IListValueProperty
‣ Representation of the property instance
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
‣ single value: IValueProperty
‣ list value: IListValueProperty
‣ Representation of the property instance
‣ single value: IObservableValue
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
‣ single value: IValueProperty
‣ list value: IListValueProperty
‣ Representation of the property instance
‣ single value: IObservableValue
‣ list value: IObservableList
Montag, 28. Oktober 13
Eclipse Databinding
‣ Eclipse Databinding is Domain-Model-Type agnostic
‣ Abstract representation of a property
‣ single value: IValueProperty
‣ list value: IListValueProperty
‣ Representation of the property instance
‣ single value: IObservableValue
‣ list value: IObservableList
‣ 2 instance can be synced through the DatabindingContext
Montag, 28. Oktober 13
Eclipse Databinding
Montag, 28. Oktober 13
Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories
Montag, 28. Oktober 13
Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories
‣ JavaBeanProperties, EMFProperties
e.g. [Link]([Link].CURRENCY__NAME);
Montag, 28. Oktober 13
Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories
‣ JavaBeanProperties, EMFProperties
e.g. [Link]([Link].CURRENCY__NAME);
‣ JFXUIProperty for properties of JavaFX-Controls
e.g. [Link]()
Montag, 28. Oktober 13
Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories
‣ JavaBeanProperties, EMFProperties
e.g. [Link]([Link].CURRENCY__NAME);
‣ JFXUIProperty for properties of JavaFX-Controls
e.g. [Link]()
‣ Creation of IObservableValue
Montag, 28. Oktober 13
Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories
‣ JavaBeanProperties, EMFProperties
e.g. [Link]([Link].CURRENCY__NAME);
‣ JFXUIProperty for properties of JavaFX-Controls
e.g. [Link]()
‣ Creation of IObservableValue
‣ simple: IValueProperty#observe(Object)
Montag, 28. Oktober 13
Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories
‣ JavaBeanProperties, EMFProperties
e.g. [Link]([Link].CURRENCY__NAME);
‣ JFXUIProperty for properties of JavaFX-Controls
e.g. [Link]()
‣ Creation of IObservableValue
‣ simple: IValueProperty#observe(Object)
‣ master-detail: IValueProperty#observeDetail(IObservableValue)
Montag, 28. Oktober 13
Lab DB
‣ Bind TextFields
‣ Update based on selection
‣ Change ListView to keep up-to-date
Montag, 28. Oktober 13
Lab Eclipse DB
‣ In the Main#start call [Link]()
‣ In CurrencyController create and initialize a field of type
WritableValue
‣ In the initialize-method
‣ Create an instance of EMFDatabindingContext
‣ Create an instance IValueProperty for CURRENCY__NAME -
through EMFProperties, [Link]
‣ Create an instance IValueProperty for TextField#text property
through JFXUIProperties
‣ Create an observable of the name IValueProperty#observeDetail
‣ Create an observable of the text IValueProperty#observe
Montag, 28. Oktober 13
Lab Eclipse DB
‣ Repeat the steps for the CURRENCY__SYMBOL
‣ add an InvalidationListener to the currencyList‘s selectionModel
and when call update master using IObservableValue#setValue
‣ Notice when running: ListCell is not updated!!!
‣ Create an IValueProperty for CURRENCY__NAME
‣ Replace the list-setup through [Link](ListView,IValueProperty)
Montag, 28. Oktober 13
Deployment
‣ The optimal way to deploy JavaFX applications is
‣ Through the native install format ([Link], dmg, rpm,
deb)
‣ The JRE included so that no prerequisits are needed
(e.g. Mac App Store requirement)
‣ JavaFX provides packageing tasks
‣ Can be call on command line
‣ Ant integration
‣ e(fx)clipse has a special file to configure the export
named .fxbuild
Montag, 28. Oktober 13
Lab Deploy
‣ Generate a native installer
Montag, 28. Oktober 13
Lab Deployment
‣ Open the [Link]-File
‣ Enter infos into:
‣ Vendor name: MY COMPANY
‣ Application title: My App
‣ Application version: 1.0.0
‣ Application class: [Link]
‣ Toolkit Type: fx
‣ Packaging Format: all
‣ Click on „ant [Link] and run“
Montag, 28. Oktober 13
FX & OSGi
Montag, 28. Oktober 13
FX & OSGi
‣ JavaFX and OSGi are not natural friends
‣ JavaFX is not JSRed hence it‘s in none of the OSGi-EEs
‣ JavaFX is part of the JDK7 but not on a classpath
‣ JavaFX is on the extension classpath in JDK8 but Equinox
by default skips the extension classpath
‣ Most APIs have been adjusted to be OSGi-friendly (e.g.
FXMLLoader takes a classloader)
‣ e(fx)clipse solves the integration problem for JDK7/8 in
Kepler with a Adaptor Hook
‣ Fragment to the [Link] ([Link])
‣ Fake bundle with JavaFX-packages ([Link])
Montag, 28. Oktober 13
Lab FX & OSGi
‣ Create an FX-OSGi project
‣ Load an FXML-File
Montag, 28. Oktober 13
Lab FX & OSGi
‣ Setup a target platform (Preferences > Target Platform)
‣ Add a new empty target
‣ Point it to the target-directory of the downloaded zip-
Folder
‣ Create a new project using File > New Project ... > OSGi
Application Project
‣ Enter the following data on page 1
‣ Bundle-ID-Prefix: [Link]
‣ Execution Environment: JavaSE-1.8
‣ On the next page enter:
‣ Product Name: MyOSGiApp
‣ Eclipse DI: checked
Montag, 28. Oktober 13
Lab FX & OSGi
‣ Create an FXGraph-File (BorderPane)
‣ Add a button
‣ Load the FXML-File in the the run-method
‣ Launch the application useing the generated launch config
‣ Create a controller
‣ Add the controller to the FXGraph-File
‣ Connect the button with the controller
‣ Connect the onAction-property and update the button text
‣ Launch the application => Crash!
‣ Reason is that the FXMLLoader does not know the bundle
with the controller class
Montag, 28. Oktober 13
Lab FX & OSGi
‣ Solving the classloader problem
‣ Solve it your own
‣ Let Eclipse DI solve it
@Inject
@FXMLLoader
FXMLLoaderFactory factory;
// ...
BorderPane pane = (BorderPane) [Link]("[Link]").load();
Montag, 28. Oktober 13
Unit Test
Montag, 28. Oktober 13
Unit Test
‣ Junit-Testing is done with Jemmy + JemmyFX
‣ JavaFX-applications can be queried for elements
e.g. find the first button the scene is
Lookup<Button> lookup = [Link]().lookup([Link], new
LookupCriteria<Button>() {
@Override
public boolean check(Button arg0) {
return true;
}
});
‣ Each type is wrapped in a class named Wrap<T>
‣ Mouse/Keyboard input is emulated through the Wrap
e.g. single click on button
[Link]().mouse().click()
Montag, 28. Oktober 13
Lab Unit Test
‣ Writing a simple Unit-Test
Montag, 28. Oktober 13
Lab Unit Test
‣ Open the generated SampleTestCase
‣ Modify the content of the test-method
‣ Search for button class using LookupCriteria
‣ Execute a single click
‣ Access the native control and check that the text has
changed
‣ Run the junit-test through the created ...[Link]-
Config
Montag, 28. Oktober 13
FX + e4
Montag, 28. Oktober 13
FX + e4
‣ e(fx)clipse provides a render implementation for JavaFX
‣ The programming model (DI, Services) are the same
‣ The application model is the same
‣ Exploits JavaFX possibilities
‣ e.g Animation to for Window open/close, Perspective
switching
‣ Generic Framework writing own renderers extremely easy!
‣ UI(=PartContent) has to be rewritten in JavaFX
Montag, 28. Oktober 13
Lab FX + e4
‣ Developing an application
Montag, 28. Oktober 13
Lab FX + e4
‣ Create an e4 JavaFX project using File > New Project ... >
JavaFX/OSGi/e4 Application projects
‣ Enter the following data on page 1:
‣ Bundle-ID-Prefix: [Link]
‣ Execution Environment: JavaSE-1.8
‣ On page 2
‣ Product Name: MyE4App
‣ In the generated [Link]-project create named
application-package
‣ Copy CurrencyController, [Link] and [Link] from
your FXGraphProject
Montag, 28. Oktober 13
Lab FX + e4
‣ Add the following dependencies
‣ [Link]
‣ [Link]
‣ Create a libs directory
‣ Copy [Link].model_......jar to it
‣ Open the [Link] and switch to Runtime-Tab
‣ In the lower right click add select the jar you copied
to libs
‣ Create a class named CurrencyPart
Montag, 28. Oktober 13
Lab FX + e4
‣ Make the CurrencyPart look like this:
@Inject
@FXMLLoader
FXMLLoaderFactory factory;
@PostConstruct
void initUI(BorderPane pane) {
try {
[Link]((Node) [Link]("[Link]")
.resourceBundle([Link]("[Link]"))
.load());
} catch (IOException e) {
// TODO Auto-generated catch block
[Link]();
}
}
Montag, 28. Oktober 13
Lab FX + e4
‣ Open the Application.e4xmi
‣ Add a TrimmedWindow below Windows
‣ Set x,y,w,h to 0,0,600,600
‣ Add a PartStack in Controls
‣ Add a Part in the stack
‣ Set the Label to Currency
‣ Set the class URI pointing to CurrenyPart
‣ Launch through the provided launch config
Montag, 28. Oktober 13
SonF - SWT on FX
Montag, 28. Oktober 13
What is it?
‣ SonF is an experimental SWT implement based on JavaFX
‣ Target: reaching compilance level of RWT
‣ None-Target (as of now): Running Eclipse IDE on SonF
‣ Things working mostly
‣ Controls: Text, Label, List, Table, Tree, TabFolder, ...
‣ Layouts
‣ Canvas!
‣ Parts of StyledText
‣ AS OF TODAY NOT AVAILABLE FOR FREE USE
‣ experminental (many things still not working)
‣ decision if it gets OSS not yet made
Montag, 28. Oktober 13
Wanna see an example
Montag, 28. Oktober 13
Resources
‣ e(fx)clipse - [Link]
‣ CSS-Ref - [Link]
scene/doc-files/[Link]
‣ FXML-Ref: [Link]
doc-files/introduction_to_fxml.html
‣ SceneBuilder: [Link]
javafx/tools/[Link]
‣ JavaFX Blog: [Link]
‣ My Blog: [Link]
Montag, 28. Oktober 13