0% found this document useful (0 votes)
126 views130 pages

Javafx Tutorial: Tom Schindl

This document provides an overview of JavaFX and tutorials for creating JavaFX applications. It discusses the anatomy of a JavaFX application including the base Application class and stages. It also covers JavaFX properties, layouts, and using FXML to declaratively define JavaFX user interfaces. The included labs guide readers through creating their first JavaFX application, working with JavaFX properties and bindings, and exploring different layout options.

Uploaded by

valdomiromorais
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
126 views130 pages

Javafx Tutorial: Tom Schindl

This document provides an overview of JavaFX and tutorials for creating JavaFX applications. It discusses the anatomy of a JavaFX application including the base Application class and stages. It also covers JavaFX properties, layouts, and using FXML to declaratively define JavaFX user interfaces. The included labs guide readers through creating their first JavaFX application, working with JavaFX properties and bindings, and exploring different layout options.

Uploaded by

valdomiromorais
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 130

JavaFX Tutorial

Tom Schindl <[email protected]>

Montag, 28. Oktober 13


About Me

‣ CTO BestSolution.at 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 javafx.application.Application;

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 javafx.application.Application;

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 javafx.application.Application;

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 javafx.application.Application;

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

primaryStage.setScene(scene);
primaryStage.show(); Display

Montag, 28. Oktober 13


Anatomy of an FX-App
import javafx.application.Application;

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

primaryStage.setScene(scene);
primaryStage.show(); 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$.tar.gz/.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 „eclipse.vm“

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 javafx.scene.control.Button 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");
b.setOnAction(new EventHandler<ActionEvent>() {

@Override
public void handle(ActionEvent event) {
System.out.println("Hello World via setOnAction!");
}
});
b.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {

@Override
public void handle(ActionEvent event) {
System.out.println("Hello World via addEventHandler!");
}
});
root.setCenter(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: javafx.beans.property.Property

‣ readonly: javafx.beans.property.ReadOnlyProperty

‣ 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) {


support.firePropertyChange("name", this.name, this.name = name);
}

public String getName() {


return this.name;

}
}

Montag, 28. Oktober 13


FX-Properties

public class JavaFXBean {


private StringProperty name = new SimpleStringProperty(this,"name");

public void setName(String name) {


this.name.set(name);
}

public String getName() {


return this.name.get();
}

public StringProperty nameProperty() {


return this.name;
}
}

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: javafx.scene.control.TextField

‣ center: javafx.scene.text.Text

‣ left: javafx.scene.control.Slider (hint: orientation!)

‣ right: javafx.scene.control.Slider

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

‣ javafx.scene.layout.BorderPane

‣ javafx.scene.layout.HBox

‣ javafx.scene.layout.VBox

‣ javafx.scene.layout.GridPane

‣ Layout constraints are applied through constant setters

BorderPane root = new BorderPane();


Button child = new Button("Layout Test");
BorderPane.setAlignment(child, Pos.CENTER_LEFT);
root.setCenter(child);

Montag, 28. Oktober 13


FX Layouts

‣ Additional layouts

‣ SWT-Layouts part of e(fx)clipse

‣ org.eclipse.fx.ui.panes.GridLayoutPane

‣ org.eclipse.fx.ui.panes.FillLayoutPane

‣ org.eclipse.fx.ui.panes.RowLayoutPane

‣ MigPane (http://www.miglayout.com/)

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: b.setText("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 javafx.scene.layout.HBox?> import javafx.scene.control.Button;


<?import javafx.scene.control.Button?> import javafx.scene.layout.HBox;

<HBox xmlns:fx="http://javafx.com/fxml"> HBox box = new HBox();


<children>
<Button Button button = new Button("Hello World");
text="Hello World">
</Button> box.getChildren().add(button);
</children>
</HBox>

Montag, 28. Oktober 13


FXML

‣ Executing actions
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>

<HBox xmlns:fx="http://javafx.com/fxml"
fx:controller="application.SampleController">
<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 javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>

<HBox xmlns:fx="http://javafx.com/fxml"
fx:controller="application.SampleController"> 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 javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>

<HBox xmlns:fx="http://javafx.com/fxml"
fx:controller="application.SampleController"> 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 javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>

<HBox xmlns:fx="http://javafx.com/fxml"
fx:controller="application.SampleController"> 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 javafx.scene.layout.BorderPane?>
import javafx.fxml.FXML;
<?import javafx.scene.layout.HBox?>
import javafx.scene.control.Button;
<?import javafx.scene.control.Button?>

public class SampleController {


<HBox xmlns:fx="http://javafx.com/fxml"
@FXML Button mybutton;
fx:controller="application.SampleController">
<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 BorderPane.alignment="CENTER_LEFT">

‣ complex constraints: <BorderPane.margin><Insets le!="10"></Insets></


BorderPane.margin>

‣ i18n support

‣ prefix value with %: <Button fx:id="mybutton" text="%hello.world">

‣ preview: <?scenebuilder-preview-i18n-resource messages.properties?>

‣ media resource support

‣ prefix value with @: <Image url="@Money-icon_48.png" />

‣ loading FXML-Files using javafx.fxml.FXMLLoader.load

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: javafx.scene.layout.BorderPane

‣ 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 Sample.fxml

‣ 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 messages.properties-File

‣ Add a key „hello.world“

‣ Update the FXML to use hello.world

‣ Update the Main-Code to use FXMLLoader.load(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 javafx.scene.layout.BorderPane
import application.SampleController
import javafx.scene.control.Button

component Sample resourcefile "messages.properties" controlledby SampleController {


BorderPane {
center : Button {
text : "Hello World"
}
}
}

Montag, 28. Oktober 13


FXGraph
package application

import javafx.scene.layout.BorderPane
import application.SampleController
import javafx.scene.control.Button

component Sample resourcefile "messages.properties" controlledby SampleController {


BorderPane {
center : Button {
text : "Hello World"
}
} Filename
}

Montag, 28. Oktober 13


FXGraph
package application

import javafx.scene.layout.BorderPane
import application.SampleController
import javafx.scene.control.Button

component Sample resourcefile "messages.properties" controlledby SampleController {


BorderPane {
center : Button {
text : "Hello World" Translations
}
} Filename
}

Montag, 28. Oktober 13


FXGraph
package application

import javafx.scene.layout.BorderPane
import application.SampleController
import javafx.scene.control.Button

component Sample resourcefile "messages.properties" 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 "hello.world" }

‣ 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 application.CurrencyController {


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 application.CurrencyController {


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 application.CurrencyController {


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: javafx.scene.layout.BorderPane

‣ Filename: Currency

‣ Controller Name: CurrencyController

Montag, 28. Oktober 13


Lab FXGraph

‣ Create the UI

Montag, 28. Oktober 13


Lab FXGraph
‣ Put another javafx.scene.layout.BorderPane in the left-Property

‣ put a javafx.scene.control.ListView in the center

‣ put a javafx.scene.layout.HBox in the bottom

‣ add 2 javafx.scene.control.Button as the children

‣ Put javafx.scene.layout.GridPane in the center Property


(Hint row, colum-index and hgrow can be set using static)

‣ add a javafx.scene.control.Label (text=Name)

‣ add a javafx.scene.control.TextField

‣ add a javafx.scene.control.Label (text=Abbreviation)

‣ add a javafx.scene.control.TextField

Montag, 28. Oktober 13


Lab FXGraph
‣ Create a file messages.properties

‣ Add the following keys with translations:


common.add
common.remove
currency.name
currency.abbrev

‣ Modify Currency.fxgraph adding resourcefile "messages.properties" 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 http://docs.oracle.com/javafx/2/api/javafx/
scene/doc-files/cssref.html

‣ 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 application.css 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<>();


currencyList.setCellFactory(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
currencyList.setCellFactory(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
currencyList.setCellFactory(new Callback<ListView<Currency>, ListCell<Currency>>() {

@Override
public ListCell<Currency> call(ListView<Currency> param) {
return new CurrencyCell();
}
});

ListView<Currency> currencyList = new ListView<>();


currencyList.setCellFactory((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(item.getName());
} else {
setText(null);
}
super.updateItem(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. EMFProperties.value(MyfondPackage.Literals.CURRENCY__NAME);

Montag, 28. Oktober 13


Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories

‣ JavaBeanProperties, EMFProperties
e.g. EMFProperties.value(MyfondPackage.Literals.CURRENCY__NAME);

‣ JFXUIProperty for properties of JavaFX-Controls


e.g. JFXUIProperties.text()

Montag, 28. Oktober 13


Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories

‣ JavaBeanProperties, EMFProperties
e.g. EMFProperties.value(MyfondPackage.Literals.CURRENCY__NAME);

‣ JFXUIProperty for properties of JavaFX-Controls


e.g. JFXUIProperties.text()

‣ Creation of IObservableValue

Montag, 28. Oktober 13


Eclipse Databinding
‣ Creation of IValueProperty instances is done through
Factories

‣ JavaBeanProperties, EMFProperties
e.g. EMFProperties.value(MyfondPackage.Literals.CURRENCY__NAME);

‣ JFXUIProperty for properties of JavaFX-Controls


e.g. JFXUIProperties.text()

‣ 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. EMFProperties.value(MyfondPackage.Literals.CURRENCY__NAME);

‣ JFXUIProperty for properties of JavaFX-Controls


e.g. JFXUIProperties.text()

‣ 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 JFXRealm.createDefault()

‣ 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, MyfondPackage.Literals

‣ 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 ListUtil.setupList(ListView,IValueProperty)

Montag, 28. Oktober 13


Deployment
‣ The optimal way to deploy JavaFX applications is

‣ Through the native install format (setup.exe, 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 build.fxbuild-File

‣ Enter infos into:

‣ Vendor name: MY COMPANY

‣ Application title: My App

‣ Application version: 1.0.0

‣ Application class: application.Main

‣ Toolkit Type: fx

‣ Packaging Format: all

‣ Click on „ant build.xml 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 system.bundle (org.eclipse.fx.osgi)

‣ Fake bundle with JavaFX-packages (org.eclipse.fx.javafx)

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: osgi.sample

‣ 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) factory.loadRequestorRelative("Sample.fxml").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 = scene.asParent().lookup(Button.class, 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
lookup.wrap().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 ...jemmy.launch-


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: e4.sample

‣ Execution Environment: JavaSE-1.8

‣ On page 2

‣ Product Name: MyE4App

‣ In the generated e4.sample.app-project create named


application-package

‣ Copy CurrencyController, Currency.fxgraph and messages.properties from


your FXGraphProject

Montag, 28. Oktober 13


Lab FX + e4
‣ Add the following dependencies

‣ org.eclipse.emf.ecore

‣ org.eclipse.emf.databinding

‣ Create a libs directory

‣ Copy at.bestsolution.myfond.model_......jar to it

‣ Open the MANIFEST.MF 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 {
pane.setCenter((Node) factory.loadRequestorRelative("Currency.fxml")
.resourceBundle(ResourceBundle.getBundle("application.messages"))
.load());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

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 - http://www.efxclipse.org

‣ CSS-Ref - http://docs.oracle.com/javafx/2/api/javafx/
scene/doc-files/cssref.html

‣ FXML-Ref: http://docs.oracle.com/javafx/2/api/javafx/fxml/
doc-files/introduction_to_fxml.html

‣ SceneBuilder: http://www.oracle.com/technetwork/java/
javafx/tools/default-1568085.html

‣ JavaFX Blog: http://fxexperience.com/

‣ My Blog: http://tomsondev.bestsolution.at/

Montag, 28. Oktober 13

You might also like