SlideShare a Scribd company logo
1 of 94
Download to read offline
Thierry Wasylczenko
@twasyl
#JavaFX.forReal()
martine mocht den Code
ElsassJUG
Disclaimer
Swing lovers won’t be hurt and no beard or mustach will be shaved.
You will maybe discover new technologies or concepts. Don’t be
afraid.
The presentation of technologies are not promotional.
SlideshowFX is my own open source project and will only be used as
an example of implementations of technologies presented.
2
presentation.agenda()
public class Presentation extends Application {
public void init() { Speaker.load("twasyl"); }
public void start(Stage stage) {
JavaFX.getVersion(8).load();
new ScriptEngineManager().getEngineByName("nashorn");
Bundle.deploy("OSGi");
Markups.stream().filter(m -> m.name.equals("asciidoctor")));
vertx.createHttpServer().listen(8080, "localhost");
leapMotionController.isConnected();
}
public void stop() { Speaker.shutdown("twasyl"); }
}
3
4
5
6
#JavaFX 8
7
<2 />
<8>
FXML
FXML-the easy one
<BorderPane xmlns:fx="http://javafx.com/fxml">
<top>
<MenuBar>
<Menu text="File">
<MenuItem text="Quit" />
</Menu>
</MenuBar>
</top>
<center>
<FlowPane>
<Button text="Show" />
<Button text="more" />
</FlowPane>
</center>
</BorderPane>
10
FXML-the controller
• The backend of FXML
• Associated to the view
public class MyController implements Initializable {
// Some interesting things to code
@Override
public void initialize(URL url, ResourceBundle resourceBundle)
// Some other interesting things to code !
}
}
11
FXML + controller
<BorderPane fx:controller="com.SuperController">
<center>
<Button text="Click !" fx:id="myButton"
onAction="#doSomething" />
</center>
</BorderPane>
public class SuperController implements Initializable {
@FXML private Button myButton;
@FXML private void doSomething(ActionEvent e) {}
}
12
FXML-fx:define
<BorderPane fx:controller="com.SuperController">
<fx:define>
<Double fx:id="MY_DOUBLE" fx:value="20.0" />
</fx:define>
<center>
<TextField text="$MY_DOUBLE" />
</center>
</BorderPane>
13
FXML-fx:factory
...
<ComboBox promptText="IP address">
<items><NetworkUtils fx:factory="getObservableIPs" /></items>
</ComboBox>
...
public class NetworkUtils {
public static ObservableList<String> getObservableIPs() {
/* ... */
}
}
14
FXML-fx:reference
<BorderPane fx:controller="com.SuperController">
<fx:define>
<TabPane fx:id="myTabPane" />
<FXCollections fx:id="myList" fx:factory="observableArrayList"
<fx:reference source="myTabPane" />
</FXCollections>
</fx:define>
<center>
<fx:reference source="myTabPane" />
</center>
</BorderPane>
15
Customization
• CSS
• Inline
• Stylesheets
• Programmatically
• Custom pseudo state
• A component’s type = a CSS class
• Button   .button
• TextField   .text-field
• ...
Customization 17
Customization -CSS
<AnchorPane>
<stylesheets>
<URL value="@/path/of/your/stylesheet.css" />
</stylesheets>
<Button text="Button 1" style="-fx-background-color: red" />
<Button text="Button 2" class="my-super-class" />
</AnchorPane>
button1.setStyle("-fx-text-fill: white");
button2.getStyleClass().add("my-super-class");
18
Customization -Pseudo state
PseudoClass ps = PseudoClass.getPseudoClass("awesome");
myButton.pseudoClassStateChanged(ps, true);
.button:awesome {
-fx-text-fill: orange;
}
#myButton:awesome {
-fx-text-fill: green;
}
19
• Fully customized UI
• CSS already known
• Specifities
• Not always that easy
Customization
REX
20
Properties
Properties -types
IntegerProperty intP = new SimpleIntegerProperty();
DoubleProperty doubleP = new SimpleDoubleProperty();
// ...
BooleanProperty booleanP = new SimpleBooleanProperty();
StringProperty stringP = new SimpleStringProperty();
ObjectProperty<Conference> objectP = new SimpleObjectProperty<>();
22
Properties -binding
IntegerProperty intP1 = new SimpleIntegerProperty();
IntegerProperty intP2 = new SimpleIntegerProperty();
intP1.bind(intP2);
intP2.set(10);
System.out.println("And P1? " + intP1.get());
23
Properties -binding
IntegerProperty intP1 = new SimpleIntegerProperty();
IntegerProperty intP2 = new SimpleIntegerProperty();
intP1.bindBidirectional(intP2);
intP2.set(10);
System.out.println("And P1? " + intP1.get());
intP1.set(20);
System.out.println("And P2? " + intP2.get());
24
Properties -Events
IntegerProperty intP1 = new SimpleIntegerProperty();
intP1.addListener((valueInt, oldInt, newInt) -> {
System.out.println("Change");
});
intP1.set(10);
25
Properties -POJO 2.0
public class Conference {
private StringProperty name = new SimpleStringProperty();
public StringProperty nameProperty() { return this.name; }
public String getName() { return this.name.get(); }
public void setName(String name) { this.name.set(name); }
}
final Conference jug = new Conference();
tf.textProperty().bindBidirectional(jug.nameProperty());
26
Not serializable
Properties -POJO 1.5
public class Conference {
private PropertyChangeStatus pcs =
new PropertyChangeStatus(this);
private String name;
public void addPropertyChangeListener(PropertyChangeListener list
this.pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener l
this.pcs.removePropertyChangeListener(listener);
}
28
Properties -POJO 1.5
public class Conference {
// ...
public void addPropertyChangeListener(String propertyName, Proper
this.pcs.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(String propertyName, Pro
this.pcs.removePropertyChangeListener(propertyName, listener);
}
// ...
}
29
Properties -POJO 1.5
public class Conference {
// ...
public String getName() { return this.name; }
public void setName(String name) {
final String old = this.name;
this.name = name;
this.pcs.firePropertyChange("name", old, this.name);
}
}
30
Properties -POJO 1.5
final Conference jug = new Conference();
JavaBeanStringPropertyBuilder builder = new ...
JavaBeanStringProperty nameProperty = builder.bean(jug)
.name("name")
.build();
nameProperty.addListener((valueName, oldIName, newName) -> {
// ...
});
31
Controls
ImageView
ImageView-FXML
<ImageView>
<image>
<Image url="@/path/to/my-image.png" preserveRatio="true"
smooth="true" backgroundLoading="true"
requestedHeight="20" requestedWidth="20" />
</image>
</ImageView>
34
ImageView-Java
final URL url = ...
final InputStream stream = ...
final Image image1 = new Image(url, true);
final Image image2 = new Image(stream);
final ImageView view = new ImageView(image1);
• Prefer the Image contructor with a URL
35
WebView
WebView-the State
final WebView browser = new WebView();
browser.getEngine().stateProperty().addListener((stateValue, oldSta
if(newState == Worker.State.SUCCEEDED) {
final Element div = browser.getEngine().getDocument()
.getElementById("twasyl");
if(div != null) {
div.getTextContent();
}
}
});
37
WebView-interact with events
• When the page sends event:
webEngine.setOnAlert(event -> { /* ... */ } );
webEngine.setOnError(event -> { /* ... */ } );
webEngine.setPromptHandler(event -> { /* ... */ } );
38
• WebHistory
• int getMaxSize()
• ObservableList<WebHistory.Entry>
getEntries()
• WebHistory.Entry
• Date getLastVisitedDate()
• String getTitle()
• String getUrl()
WebView-history 39
• Stylesheet inheritance
• HTML buttons inherit from JavaFX
buttons
• ...
• Performance
WebView
REX
40
TableView
TableView-basics
@FXML private TableView<Conference> confs;
@Override public void initialize(URL location, ResourceBundle bundl
final Conference conf1 = new Conference("BreizhJUG");
final Conference conf2 = new Conference("NantesJUG");
final Conference conf3 = new Conference("NormandyJUG");
final Conference conf4 = new Conference("ElsassJUG");
this.confs.getItems().addAll(conf1, conf2, conf3, conf4);
}
42
TableView-display an image 1/3
public class ImageCell extends TableCell<Conference, Image> {
protected void updateItem(Image item, boolean empty) {
if(!empty && item != null) {
final ImageView view = new ImageView(item);
setGraphic(view);
} else {
setGraphic(null);
}
}
}
43
TableView-display an image 2/3
public class ImageCellFactory implements
Callback<TableColumn<Conference, Image>,
TableCell<Conference, Image>> {
@Override
public TableCell<Conference, Image> call(TableColumn<Conference,
final TableCell<Conference, Image> cell =
new ImageCell<Conference, Image>();
return cell;
}
}
44
TableView-display an image 3/3
@FXML private TableView<Conference> confs;
@Override public void initialize(URL location, ResourceBundle bundl
final TableColumn<Conference, Image> logoColumn =
new TableColumn<>("Logo");
logoColumn.setCellValueFactory(
new PropertyValueFactory<Conference, Image>("logo")
);
logoColumn.setCellFactory(new ImageCellFactory());
this.confs.getColumns().add(logoColumn);
}
45
TableView-FXML
<TableView fx:id="confs">
<columns>
<TableColumn text="Logo">
<cellValueFactory>
<PropertyValueFactory property="logo" />
</cellValueFactory>
<cellFactory> <ImageCellFactory /> </cellFactory>
</TableColumn>
</columns>
</TableView>
46
Concurrency
• Questions:
1. How to not block my UI when I
download a file ?
2. How to work with the file when
download is done ?
• javafx.concurrent
• Worker
• Task
• Service
• ScheduledService
concurrency.setTricky(true) 48
• Implements Worker
• Task#updateMessage(String)
• Task#updateProgress(long,long)
• Task#get() // blocking
• Task#getValue() // non-blocking
• Task#succeeded()
• Task#running()
• Task#failed()
• Task#cancelled()
• Worker.State
Concurrency-Task 49
Concurrency-Task example 1/2
public class DownloadPresentationTask extends Task<File> {
@Override
protected File call() throws Exception {
return new File("awesome.pdf");
}
@Override
protected void succeeded() {
super.succeeded();
this.updateMessage("Download successful");
this.updateProgress(0, 0);
}
}
50
Concurrency-Task example 2/2
final DownloadPresentationTask task = new DownloadPresentationTask(
task.stateProperty().addListener((value, oldState, newState) -> {
if(newState == Worker.State.SUCCEEDED
&& task.getValue() != null) {
// Do awesome things
}
});
new Thread(task).start();
51
Packaging
• Native applications
• Embed a JRE
• No need to download a JRE
• javafxpackager tool
• Ant tasks
Packaging 53
UI testing
• Automaton
• Support both Swing and JavaFX 2
• Works with JavaFX 8
• Tests can be written in groovy
• TestFX
• Very fluent API
UI testing 55
Tooling
SceneBuilder
• FXML WYSIWYG editor + CSS support
57
Scenic View 58
#JavaScript
59
• Execute standalone JavaScript
function sayHello(name) {
print("Hello " + name);
}
sayHello('Thierry');
$ jjs hello.js
Hello Thierry
Nashorn 60
• Execute Java from JavaScript
$ jjs java.js
[Hello, world]
Nashorn
function displayList() {
var ArrayList = Java.type('java.util.ArrayList'
var lst = new ArrayList();
lst.add("Hello");
lst.add("world");
print(lst);
}
61
Nashorn -embedding
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
engine.eval("function sum(a, b) { return a + b; }");
System.out.println(engine.eval("sum(1, 2);"));
62
• Useful ?
• Web-based app
• One browser to test
• Web developer for front
• Java deveveloper for back
• SlideshowFX
• Polyglotism
Nashorn -JavaFX 63
Nashorn -JavaFX
WebView webView = new WebView();
// Make a Java object available in the page
JSObject window = (JSObject) webView.getEngine()
.executeScript("window");
window.setMember("sfx", SlideshowFXController.this);
// Execute some JavaScript
webView.getEngine().executeScript("sum(1, 2);");
64
• What’s done:
• DOM manipulation
• Get current slide
• Inject custom JS libraries
• Advantages
• JavaFX – HTML communication
• Tip
• Use Base64 strings for interopability
Nashorn -SlideshowFX
REX
65
#OSGi
66
• Jigsaw will bring modularity
• Penrose : explore interoperability between
Jigsaw & OSGi
• For now: modularity = OSGi
In Jigsaw's shadow 67
• The Dynamic Module System for Java
• June 2014
• OSGi Release 6
• ClassPath
• Handle it or die
OSGi -Huh? 68
• OSGi container
• Apache Felix
• Apache Karaf
• eclipse equinox
• Services
• To be registered
OSGi -services 69
OSGi -embedding
Map configurationMap = new HashMap<>();
configurationMap.put("org.osgi.framework.bootdelegation",
"sun.misc, javax.*, javafx.*");
configurationMap.put("felix.auto.deploy.action", "install,start"
// Starting OSGi
FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFac
Framework osgiFramework = frameworkFactory.newFramework(configurati
try {
osgiFramework.start();
LOGGER.fine("OSGI container has bee started successfully");
} catch (BundleException e) {
LOGGER.log(Level.SEVERE, "Can not start OSGi server");
}
70
OSGi -deploy services
Bundle bundle = null;
try {
bundle = osgiFramework.getBundleContext()
.installBundle("file:/Users/twasyl/MyBundle.jar");
} catch (BundleException e) {
// Log
}
if(bundle != null) {
try {
bundle.start();
} catch (BundleException e) {
// Log
}
}
71
OSGi -JavaFX tips
FXMLLoader loader = new FXMLLoader(getClass().getClassLoader()
.getResource("/path/to/my.fxml"));
Pane root = null;
try {
// Tip: need to set the ClassLoader
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
this.controller = loader.getController();
} catch (IOException e) {
// Log
}
72
• What’s done
• Embed Felix
• Support new syntax
• Add extensions
• Add hosting connectors
• Advantage
• Extend the app without modifying the
app
• Tips
• Think ClassLoader
• Think boot delegation
OSGi -SlideshowFX
REX
73
#asciidoctor
74
• Simplified syntax for complex rendering
• Diagrams
• Formulas
• Written in Ruby
• Ports
• JavaScript
• JVM
The popular syntax 75
AsciidoctorJ & OSGi
• Parse asciidoctor in Java
• from files
• from strings
RubyInstanceConfig config = new RubyInstanceConfig();
config.setLoader(AsciidoctorMarkup.class.getClassLoader());
JavaEmbedUtils.initialize(Arrays.asList(
"META-INF/jruby.home/lib/ruby/2.0",
"gems/asciidoctor-1.5.2/lib"), config);
Asciidoctor asciidoctor = Asciidoctor.Factory
.create(AsciidoctorMarkup.class.getClassLoader());
76
Asciidoctor -Parsing
• From strings
String html = asciidoctor.convert("I'm a hero",
new HashMap<String, Object>());
• From files
File myFile = new File("myFile.adoc");
List<File> myFiles = new ArrayList<>(); // Add files then
Map<String, Object> options = new HashMap<>();
String html = asciidoctor.convertFile(myFile, options);
String[] htmls = asciidoctor.convertFiles(myFiles, options);
77
• Markup syntax
• OSGi context
• Advantage
• Trendy way to define slides' content
• Tip
• Usage in an OSGi context requires a
lot of attention
Asciidoctor -SlideshowFX
REX
78
#Vert.x
79
• Lightweight for the JVM
• Polyglot components
• Java
• JavaScript
• Groovy
• CoffeeScript
• Python
• Ruby
• ...
Innovative JVM server 80
Vert.x-Verticles
• Verticle = piece of the server
• Do some things
• Each Verticle has an instance of Vertx
public class MyVerticle extends Verticle {
@Override
public void start() {
// Do something
}
}
81
Vert.x-RouteMatcher
• Respond to requests
RouteMatcher routeMatcher = new RouteMatcher();
routeMatcher.get("/my-app/about.html", request -> { /* ... */ })
.post("/my-app/submit", request -> { /* ... */ } );
HttpServer server = vertx.createHttpServer();
server.requestHandler(routeMatcher)
.listen(8080, "192.168.218.100");
82
Vert.x-Websockets
Handler<ServerWebSocket> handler = serverWebSocket -> {
if (serverWebSocket.path().equals("/my-app")) {
// ...
} else {
serverWebSocket.reject();
}
};
HttpServer server = vertx.createHttpServer();
server.websocketHandler(handler)
.listen( 8080, "192.168.218.100");
83
Vert.x-Event Bus
• Communicating system between Verticles
• Cross Vert.x instances
Handler<Message<String>> handler = message -> {
System.out.println("Hello" + message.body());
message.reply();
};
this.vertx.eventBus().registerHandler("say.hello", handler);
this.vertx.eventBus().publish("say.hello", "Thierry");
84
Vert.x-Shared Data
• Share data between Verticles
• Not cross Vert.x instances
Map serverInfo = vertx.sharedData().getMap("serverInfo");
Set users = vertx.sharedData().getSet("users");
serverInfo.put("ip", "192.168.218.100");
users.add("thierry");
85
• What’s done
• Chat using websockets
• Quizz feature
• Twitter integration
• Advantages
• Embed a web server easily
• No installation for the client
• Tip
• Store HttpServer instances as
singleton for re-usage
Vert.x-SlideshowFX
REX
86
#LeapMotion
87
• New world, new possibilities
• Forget your mouse
• Java, C++, Unity/C#, JavaScript, Python,
Objective-C
The touchless world 88
• -Djava.library.path
• By
• platform
• architecture
• Packaging = warning
  
LeapMotion -Native libraries 89
LeapMotion -The controller
• Main interface with the device
• Access
• Frames
• Configuration information
• Use listeners
Controller leapController = new Controller();
90
LeapMotion -The listener
• Respond to events
• onInit
• onExit
• onConnect
• onDisconnect
• onFrame
Listener wonderfulListener = new WonderfulListener();
controller.addListener(listener);
91
• What’s done
• Change slides
• Show a pointer
• Perform clicks
• Advantage
• Bring interactivity
• Tip
• Think gestures
LeapMotion -SlideshowFX
REX
92
Books 93
94

More Related Content

What's hot

JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212Mahmoud Samir Fayed
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in JavaDoug Hawkins
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»SpbDotNet Community
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Anton Arhipov
 
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingJEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Danny Preussler
 
Csw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCsw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCanSecWest
 
Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1PyCon Italia
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Ryosuke Uchitate
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
The Ring programming language version 1.5.2 book - Part 76 of 181
The Ring programming language version 1.5.2 book - Part 76 of 181The Ring programming language version 1.5.2 book - Part 76 of 181
The Ring programming language version 1.5.2 book - Part 76 of 181Mahmoud Samir Fayed
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbroncymbron
 
Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance PuzzlersDoug Hawkins
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In DepthWO Community
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDanny Preussler
 

What's hot (20)

JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212
 
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloadingRiga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in Java
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloadingJEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
 
Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016
 
Csw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCsw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemes
 
Testing with Node.js
Testing with Node.jsTesting with Node.js
Testing with Node.js
 
Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1Cleanup and new optimizations in WPython 1.1
Cleanup and new optimizations in WPython 1.1
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
The Ring programming language version 1.5.2 book - Part 76 of 181
The Ring programming language version 1.5.2 book - Part 76 of 181The Ring programming language version 1.5.2 book - Part 76 of 181
The Ring programming language version 1.5.2 book - Part 76 of 181
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbron
 
Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance Puzzlers
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In Depth
 
The zen of async: Best practices for best performance
The zen of async: Best practices for best performanceThe zen of async: Best practices for best performance
The zen of async: Best practices for best performance
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and Toothpick
 

Similar to #JavaFX.forReal() - ElsassJUG

Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Tools and Techniques for Understanding Threading Behavior in Android*
Tools and Techniques for Understanding Threading Behavior in Android*Tools and Techniques for Understanding Threading Behavior in Android*
Tools and Techniques for Understanding Threading Behavior in Android*Intel® Software
 
Hibernate Import.Sql I18n
Hibernate Import.Sql I18nHibernate Import.Sql I18n
Hibernate Import.Sql I18nyifi2009
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache BeamGDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache BeamImre Nagi
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Sven Ruppert
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade ServerlessKatyShimizu
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade ServerlessKatyShimizu
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql JOYITAKUNDU1
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
Mobile Programming - Network Universitas Budi Luhur
Mobile Programming - Network Universitas Budi LuhurMobile Programming - Network Universitas Budi Luhur
Mobile Programming - Network Universitas Budi LuhurRiza Fahmi
 
Laporan multiclient chatting client server
Laporan multiclient chatting client serverLaporan multiclient chatting client server
Laporan multiclient chatting client servertrilestari08
 

Similar to #JavaFX.forReal() - ElsassJUG (20)

#JavaFX.forReal()
#JavaFX.forReal()#JavaFX.forReal()
#JavaFX.forReal()
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Ac2
Ac2Ac2
Ac2
 
Tools and Techniques for Understanding Threading Behavior in Android*
Tools and Techniques for Understanding Threading Behavior in Android*Tools and Techniques for Understanding Threading Behavior in Android*
Tools and Techniques for Understanding Threading Behavior in Android*
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Hibernate Import.Sql I18n
Hibernate Import.Sql I18nHibernate Import.Sql I18n
Hibernate Import.Sql I18n
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache BeamGDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
Mobile Programming - Network Universitas Budi Luhur
Mobile Programming - Network Universitas Budi LuhurMobile Programming - Network Universitas Budi Luhur
Mobile Programming - Network Universitas Budi Luhur
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
Laporan multiclient chatting client server
Laporan multiclient chatting client serverLaporan multiclient chatting client server
Laporan multiclient chatting client server
 

More from Thierry Wasylczenko

Du développement à la livraison avec JavaFX et le JDK9
Du développement à la livraison avec JavaFX et le JDK9Du développement à la livraison avec JavaFX et le JDK9
Du développement à la livraison avec JavaFX et le JDK9Thierry Wasylczenko
 
#Polyglottisme, une autre manière de développer une application
#Polyglottisme, une autre manière de développer une application#Polyglottisme, une autre manière de développer une application
#Polyglottisme, une autre manière de développer une applicationThierry Wasylczenko
 

More from Thierry Wasylczenko (6)

Du développement à la livraison avec JavaFX et le JDK9
Du développement à la livraison avec JavaFX et le JDK9Du développement à la livraison avec JavaFX et le JDK9
Du développement à la livraison avec JavaFX et le JDK9
 
JavaFX et le JDK9
JavaFX et le JDK9JavaFX et le JDK9
JavaFX et le JDK9
 
#Polyglottisme, une autre manière de développer une application
#Polyglottisme, une autre manière de développer une application#Polyglottisme, une autre manière de développer une application
#Polyglottisme, une autre manière de développer une application
 
Java goes wild, lesson 1
Java goes wild, lesson 1Java goes wild, lesson 1
Java goes wild, lesson 1
 
JavaFX, because you're worth it
JavaFX, because you're worth itJavaFX, because you're worth it
JavaFX, because you're worth it
 
Introduction to JavaFX 2
Introduction to JavaFX 2Introduction to JavaFX 2
Introduction to JavaFX 2
 

Recently uploaded

Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseWSO2
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxMarkSteadman7
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingWSO2
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....rightmanforbloodline
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 

Recently uploaded (20)

Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern Enterprise
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation Computing
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 

#JavaFX.forReal() - ElsassJUG

  • 2. Disclaimer Swing lovers won’t be hurt and no beard or mustach will be shaved. You will maybe discover new technologies or concepts. Don’t be afraid. The presentation of technologies are not promotional. SlideshowFX is my own open source project and will only be used as an example of implementations of technologies presented. 2
  • 3. presentation.agenda() public class Presentation extends Application { public void init() { Speaker.load("twasyl"); } public void start(Stage stage) { JavaFX.getVersion(8).load(); new ScriptEngineManager().getEngineByName("nashorn"); Bundle.deploy("OSGi"); Markups.stream().filter(m -> m.name.equals("asciidoctor"))); vertx.createHttpServer().listen(8080, "localhost"); leapMotionController.isConnected(); } public void stop() { Speaker.shutdown("twasyl"); } } 3
  • 4. 4
  • 5. 5
  • 6. 6
  • 10. FXML-the easy one <BorderPane xmlns:fx="http://javafx.com/fxml"> <top> <MenuBar> <Menu text="File"> <MenuItem text="Quit" /> </Menu> </MenuBar> </top> <center> <FlowPane> <Button text="Show" /> <Button text="more" /> </FlowPane> </center> </BorderPane> 10
  • 11. FXML-the controller • The backend of FXML • Associated to the view public class MyController implements Initializable { // Some interesting things to code @Override public void initialize(URL url, ResourceBundle resourceBundle) // Some other interesting things to code ! } } 11
  • 12. FXML + controller <BorderPane fx:controller="com.SuperController"> <center> <Button text="Click !" fx:id="myButton" onAction="#doSomething" /> </center> </BorderPane> public class SuperController implements Initializable { @FXML private Button myButton; @FXML private void doSomething(ActionEvent e) {} } 12
  • 13. FXML-fx:define <BorderPane fx:controller="com.SuperController"> <fx:define> <Double fx:id="MY_DOUBLE" fx:value="20.0" /> </fx:define> <center> <TextField text="$MY_DOUBLE" /> </center> </BorderPane> 13
  • 14. FXML-fx:factory ... <ComboBox promptText="IP address"> <items><NetworkUtils fx:factory="getObservableIPs" /></items> </ComboBox> ... public class NetworkUtils { public static ObservableList<String> getObservableIPs() { /* ... */ } } 14
  • 15. FXML-fx:reference <BorderPane fx:controller="com.SuperController"> <fx:define> <TabPane fx:id="myTabPane" /> <FXCollections fx:id="myList" fx:factory="observableArrayList" <fx:reference source="myTabPane" /> </FXCollections> </fx:define> <center> <fx:reference source="myTabPane" /> </center> </BorderPane> 15
  • 17. • CSS • Inline • Stylesheets • Programmatically • Custom pseudo state • A component’s type = a CSS class • Button   .button • TextField   .text-field • ... Customization 17
  • 18. Customization -CSS <AnchorPane> <stylesheets> <URL value="@/path/of/your/stylesheet.css" /> </stylesheets> <Button text="Button 1" style="-fx-background-color: red" /> <Button text="Button 2" class="my-super-class" /> </AnchorPane> button1.setStyle("-fx-text-fill: white"); button2.getStyleClass().add("my-super-class"); 18
  • 19. Customization -Pseudo state PseudoClass ps = PseudoClass.getPseudoClass("awesome"); myButton.pseudoClassStateChanged(ps, true); .button:awesome { -fx-text-fill: orange; } #myButton:awesome { -fx-text-fill: green; } 19
  • 20. • Fully customized UI • CSS already known • Specifities • Not always that easy Customization REX 20
  • 22. Properties -types IntegerProperty intP = new SimpleIntegerProperty(); DoubleProperty doubleP = new SimpleDoubleProperty(); // ... BooleanProperty booleanP = new SimpleBooleanProperty(); StringProperty stringP = new SimpleStringProperty(); ObjectProperty<Conference> objectP = new SimpleObjectProperty<>(); 22
  • 23. Properties -binding IntegerProperty intP1 = new SimpleIntegerProperty(); IntegerProperty intP2 = new SimpleIntegerProperty(); intP1.bind(intP2); intP2.set(10); System.out.println("And P1? " + intP1.get()); 23
  • 24. Properties -binding IntegerProperty intP1 = new SimpleIntegerProperty(); IntegerProperty intP2 = new SimpleIntegerProperty(); intP1.bindBidirectional(intP2); intP2.set(10); System.out.println("And P1? " + intP1.get()); intP1.set(20); System.out.println("And P2? " + intP2.get()); 24
  • 25. Properties -Events IntegerProperty intP1 = new SimpleIntegerProperty(); intP1.addListener((valueInt, oldInt, newInt) -> { System.out.println("Change"); }); intP1.set(10); 25
  • 26. Properties -POJO 2.0 public class Conference { private StringProperty name = new SimpleStringProperty(); public StringProperty nameProperty() { return this.name; } public String getName() { return this.name.get(); } public void setName(String name) { this.name.set(name); } } final Conference jug = new Conference(); tf.textProperty().bindBidirectional(jug.nameProperty()); 26
  • 28. Properties -POJO 1.5 public class Conference { private PropertyChangeStatus pcs = new PropertyChangeStatus(this); private String name; public void addPropertyChangeListener(PropertyChangeListener list this.pcs.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener l this.pcs.removePropertyChangeListener(listener); } 28
  • 29. Properties -POJO 1.5 public class Conference { // ... public void addPropertyChangeListener(String propertyName, Proper this.pcs.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, Pro this.pcs.removePropertyChangeListener(propertyName, listener); } // ... } 29
  • 30. Properties -POJO 1.5 public class Conference { // ... public String getName() { return this.name; } public void setName(String name) { final String old = this.name; this.name = name; this.pcs.firePropertyChange("name", old, this.name); } } 30
  • 31. Properties -POJO 1.5 final Conference jug = new Conference(); JavaBeanStringPropertyBuilder builder = new ... JavaBeanStringProperty nameProperty = builder.bean(jug) .name("name") .build(); nameProperty.addListener((valueName, oldIName, newName) -> { // ... }); 31
  • 34. ImageView-FXML <ImageView> <image> <Image url="@/path/to/my-image.png" preserveRatio="true" smooth="true" backgroundLoading="true" requestedHeight="20" requestedWidth="20" /> </image> </ImageView> 34
  • 35. ImageView-Java final URL url = ... final InputStream stream = ... final Image image1 = new Image(url, true); final Image image2 = new Image(stream); final ImageView view = new ImageView(image1); • Prefer the Image contructor with a URL 35
  • 37. WebView-the State final WebView browser = new WebView(); browser.getEngine().stateProperty().addListener((stateValue, oldSta if(newState == Worker.State.SUCCEEDED) { final Element div = browser.getEngine().getDocument() .getElementById("twasyl"); if(div != null) { div.getTextContent(); } } }); 37
  • 38. WebView-interact with events • When the page sends event: webEngine.setOnAlert(event -> { /* ... */ } ); webEngine.setOnError(event -> { /* ... */ } ); webEngine.setPromptHandler(event -> { /* ... */ } ); 38
  • 39. • WebHistory • int getMaxSize() • ObservableList<WebHistory.Entry> getEntries() • WebHistory.Entry • Date getLastVisitedDate() • String getTitle() • String getUrl() WebView-history 39
  • 40. • Stylesheet inheritance • HTML buttons inherit from JavaFX buttons • ... • Performance WebView REX 40
  • 42. TableView-basics @FXML private TableView<Conference> confs; @Override public void initialize(URL location, ResourceBundle bundl final Conference conf1 = new Conference("BreizhJUG"); final Conference conf2 = new Conference("NantesJUG"); final Conference conf3 = new Conference("NormandyJUG"); final Conference conf4 = new Conference("ElsassJUG"); this.confs.getItems().addAll(conf1, conf2, conf3, conf4); } 42
  • 43. TableView-display an image 1/3 public class ImageCell extends TableCell<Conference, Image> { protected void updateItem(Image item, boolean empty) { if(!empty && item != null) { final ImageView view = new ImageView(item); setGraphic(view); } else { setGraphic(null); } } } 43
  • 44. TableView-display an image 2/3 public class ImageCellFactory implements Callback<TableColumn<Conference, Image>, TableCell<Conference, Image>> { @Override public TableCell<Conference, Image> call(TableColumn<Conference, final TableCell<Conference, Image> cell = new ImageCell<Conference, Image>(); return cell; } } 44
  • 45. TableView-display an image 3/3 @FXML private TableView<Conference> confs; @Override public void initialize(URL location, ResourceBundle bundl final TableColumn<Conference, Image> logoColumn = new TableColumn<>("Logo"); logoColumn.setCellValueFactory( new PropertyValueFactory<Conference, Image>("logo") ); logoColumn.setCellFactory(new ImageCellFactory()); this.confs.getColumns().add(logoColumn); } 45
  • 46. TableView-FXML <TableView fx:id="confs"> <columns> <TableColumn text="Logo"> <cellValueFactory> <PropertyValueFactory property="logo" /> </cellValueFactory> <cellFactory> <ImageCellFactory /> </cellFactory> </TableColumn> </columns> </TableView> 46
  • 48. • Questions: 1. How to not block my UI when I download a file ? 2. How to work with the file when download is done ? • javafx.concurrent • Worker • Task • Service • ScheduledService concurrency.setTricky(true) 48
  • 49. • Implements Worker • Task#updateMessage(String) • Task#updateProgress(long,long) • Task#get() // blocking • Task#getValue() // non-blocking • Task#succeeded() • Task#running() • Task#failed() • Task#cancelled() • Worker.State Concurrency-Task 49
  • 50. Concurrency-Task example 1/2 public class DownloadPresentationTask extends Task<File> { @Override protected File call() throws Exception { return new File("awesome.pdf"); } @Override protected void succeeded() { super.succeeded(); this.updateMessage("Download successful"); this.updateProgress(0, 0); } } 50
  • 51. Concurrency-Task example 2/2 final DownloadPresentationTask task = new DownloadPresentationTask( task.stateProperty().addListener((value, oldState, newState) -> { if(newState == Worker.State.SUCCEEDED && task.getValue() != null) { // Do awesome things } }); new Thread(task).start(); 51
  • 53. • Native applications • Embed a JRE • No need to download a JRE • javafxpackager tool • Ant tasks Packaging 53
  • 55. • Automaton • Support both Swing and JavaFX 2 • Works with JavaFX 8 • Tests can be written in groovy • TestFX • Very fluent API UI testing 55
  • 57. SceneBuilder • FXML WYSIWYG editor + CSS support 57
  • 60. • Execute standalone JavaScript function sayHello(name) { print("Hello " + name); } sayHello('Thierry'); $ jjs hello.js Hello Thierry Nashorn 60
  • 61. • Execute Java from JavaScript $ jjs java.js [Hello, world] Nashorn function displayList() { var ArrayList = Java.type('java.util.ArrayList' var lst = new ArrayList(); lst.add("Hello"); lst.add("world"); print(lst); } 61
  • 62. Nashorn -embedding ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName("nashorn"); engine.eval("function sum(a, b) { return a + b; }"); System.out.println(engine.eval("sum(1, 2);")); 62
  • 63. • Useful ? • Web-based app • One browser to test • Web developer for front • Java deveveloper for back • SlideshowFX • Polyglotism Nashorn -JavaFX 63
  • 64. Nashorn -JavaFX WebView webView = new WebView(); // Make a Java object available in the page JSObject window = (JSObject) webView.getEngine() .executeScript("window"); window.setMember("sfx", SlideshowFXController.this); // Execute some JavaScript webView.getEngine().executeScript("sum(1, 2);"); 64
  • 65. • What’s done: • DOM manipulation • Get current slide • Inject custom JS libraries • Advantages • JavaFX – HTML communication • Tip • Use Base64 strings for interopability Nashorn -SlideshowFX REX 65
  • 67. • Jigsaw will bring modularity • Penrose : explore interoperability between Jigsaw & OSGi • For now: modularity = OSGi In Jigsaw's shadow 67
  • 68. • The Dynamic Module System for Java • June 2014 • OSGi Release 6 • ClassPath • Handle it or die OSGi -Huh? 68
  • 69. • OSGi container • Apache Felix • Apache Karaf • eclipse equinox • Services • To be registered OSGi -services 69
  • 70. OSGi -embedding Map configurationMap = new HashMap<>(); configurationMap.put("org.osgi.framework.bootdelegation", "sun.misc, javax.*, javafx.*"); configurationMap.put("felix.auto.deploy.action", "install,start" // Starting OSGi FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFac Framework osgiFramework = frameworkFactory.newFramework(configurati try { osgiFramework.start(); LOGGER.fine("OSGI container has bee started successfully"); } catch (BundleException e) { LOGGER.log(Level.SEVERE, "Can not start OSGi server"); } 70
  • 71. OSGi -deploy services Bundle bundle = null; try { bundle = osgiFramework.getBundleContext() .installBundle("file:/Users/twasyl/MyBundle.jar"); } catch (BundleException e) { // Log } if(bundle != null) { try { bundle.start(); } catch (BundleException e) { // Log } } 71
  • 72. OSGi -JavaFX tips FXMLLoader loader = new FXMLLoader(getClass().getClassLoader() .getResource("/path/to/my.fxml")); Pane root = null; try { // Tip: need to set the ClassLoader loader.setClassLoader(getClass().getClassLoader()); root = loader.load(); this.controller = loader.getController(); } catch (IOException e) { // Log } 72
  • 73. • What’s done • Embed Felix • Support new syntax • Add extensions • Add hosting connectors • Advantage • Extend the app without modifying the app • Tips • Think ClassLoader • Think boot delegation OSGi -SlideshowFX REX 73
  • 75. • Simplified syntax for complex rendering • Diagrams • Formulas • Written in Ruby • Ports • JavaScript • JVM The popular syntax 75
  • 76. AsciidoctorJ & OSGi • Parse asciidoctor in Java • from files • from strings RubyInstanceConfig config = new RubyInstanceConfig(); config.setLoader(AsciidoctorMarkup.class.getClassLoader()); JavaEmbedUtils.initialize(Arrays.asList( "META-INF/jruby.home/lib/ruby/2.0", "gems/asciidoctor-1.5.2/lib"), config); Asciidoctor asciidoctor = Asciidoctor.Factory .create(AsciidoctorMarkup.class.getClassLoader()); 76
  • 77. Asciidoctor -Parsing • From strings String html = asciidoctor.convert("I'm a hero", new HashMap<String, Object>()); • From files File myFile = new File("myFile.adoc"); List<File> myFiles = new ArrayList<>(); // Add files then Map<String, Object> options = new HashMap<>(); String html = asciidoctor.convertFile(myFile, options); String[] htmls = asciidoctor.convertFiles(myFiles, options); 77
  • 78. • Markup syntax • OSGi context • Advantage • Trendy way to define slides' content • Tip • Usage in an OSGi context requires a lot of attention Asciidoctor -SlideshowFX REX 78
  • 80. • Lightweight for the JVM • Polyglot components • Java • JavaScript • Groovy • CoffeeScript • Python • Ruby • ... Innovative JVM server 80
  • 81. Vert.x-Verticles • Verticle = piece of the server • Do some things • Each Verticle has an instance of Vertx public class MyVerticle extends Verticle { @Override public void start() { // Do something } } 81
  • 82. Vert.x-RouteMatcher • Respond to requests RouteMatcher routeMatcher = new RouteMatcher(); routeMatcher.get("/my-app/about.html", request -> { /* ... */ }) .post("/my-app/submit", request -> { /* ... */ } ); HttpServer server = vertx.createHttpServer(); server.requestHandler(routeMatcher) .listen(8080, "192.168.218.100"); 82
  • 83. Vert.x-Websockets Handler<ServerWebSocket> handler = serverWebSocket -> { if (serverWebSocket.path().equals("/my-app")) { // ... } else { serverWebSocket.reject(); } }; HttpServer server = vertx.createHttpServer(); server.websocketHandler(handler) .listen( 8080, "192.168.218.100"); 83
  • 84. Vert.x-Event Bus • Communicating system between Verticles • Cross Vert.x instances Handler<Message<String>> handler = message -> { System.out.println("Hello" + message.body()); message.reply(); }; this.vertx.eventBus().registerHandler("say.hello", handler); this.vertx.eventBus().publish("say.hello", "Thierry"); 84
  • 85. Vert.x-Shared Data • Share data between Verticles • Not cross Vert.x instances Map serverInfo = vertx.sharedData().getMap("serverInfo"); Set users = vertx.sharedData().getSet("users"); serverInfo.put("ip", "192.168.218.100"); users.add("thierry"); 85
  • 86. • What’s done • Chat using websockets • Quizz feature • Twitter integration • Advantages • Embed a web server easily • No installation for the client • Tip • Store HttpServer instances as singleton for re-usage Vert.x-SlideshowFX REX 86
  • 88. • New world, new possibilities • Forget your mouse • Java, C++, Unity/C#, JavaScript, Python, Objective-C The touchless world 88
  • 89. • -Djava.library.path • By • platform • architecture • Packaging = warning    LeapMotion -Native libraries 89
  • 90. LeapMotion -The controller • Main interface with the device • Access • Frames • Configuration information • Use listeners Controller leapController = new Controller(); 90
  • 91. LeapMotion -The listener • Respond to events • onInit • onExit • onConnect • onDisconnect • onFrame Listener wonderfulListener = new WonderfulListener(); controller.addListener(listener); 91
  • 92. • What’s done • Change slides • Show a pointer • Perform clicks • Advantage • Bring interactivity • Tip • Think gestures LeapMotion -SlideshowFX REX 92
  • 94. 94