SlideShare a Scribd company logo
1 of 44
Ten Man-Years of JavaFX: Real
World Project Experiences
JavaZone 2013
Henrik Olsson
@imheols
Session Overview
 Our experiences
– Why we chose JavaFX
– How we use JavaFX
– The great migration
– Pros, cons and tips
 Examples of JavaFX usage
 Our tools
– GuavaFX
– TestFX
 Introduction
About me
 Developer and Product Owner of LoadUI
– SmartBear Software in Stockholm
 Worked with JavaFX for ~3 years
 Contact
– henrik.olsson@smartbear.com
– linkedin.com/in/heols
 This is my first conference session
LoadUI
 Open Source load testing tool.
 Sister application of SoapUI.
Session Overview
 Our experiences
– Why we chose JavaFX
– How we use JavaFX
– The great migration
– Pros, cons and tips
 Examples of JavaFX usage
 Our tools
– GuavaFX
– TestFX
 Introduction
Illustratordesign
JavaFXimplementation
GUI as a Competitive Advantage
THE GREAT
MIGRATION
“JavaFX 1 will reach end of life (EOL)
in December.”
The JavaFX Blog, Spring 2012
“We can’t finish the migration of LoadUI until early
next year. Will we be able to redistribute our existing
LoadUI versions after the EOL date?”
SmartBear Sweden CTO, February 2012
“No, sorry.”
Oracle Representative in a phone call, February 2012
“Several software engineers have warned against
total rewrites, especially under schedule
constraints or competitive pressures.”
From Rewrite (programming) at Wikipedia
The JavaFX Blog, May 2013
“We've decided to create a workaround that will
allow anyone to redistribute the JavaFX 1
Runtime. This solution is available today…”
“The EOL is postponed to March 2013.
Redistribution of the JavaFX 1 Runtime is not an
option, for a number of reasons.”
Oracle Representative, Fall of 2012
“The deadline will be very hard to meet. Is it
possible to delay the EOL, or let us redistribute
the JavaFX 1 Runtime?” Me, Fall of 2012
“We are done with the migration!”
Me, April 2013
Migrating
 41k lines of JavaFX 1 (JavaFX Script) to 32k
lines of JavaFX 2 (Java).
– In 9 months
 JavaFX 1 and JavaFX 2 cannot co-exist.
 All code isolated in an OSGi module.
 More of a rewrite than a migration.
Performance
0
5
10
15
20
25
Windows Linux Windows Linux
JavaFX 1 JavaFX 2
JavaFX 1
Good stuff
 Flexible
 CSS
 Fun!
Pitfalls
 Poor IDE support
 Hard to debug
 License issues
 Missing basic controls
JavaFX 2
Good stuff
 Flexible
 CSS
 Fun!
Pitfalls
 Poor IDE support
 Hard to debug
 License issues
 Missing basic controls
 FXML
– MVC for real!  Multi-platform issues
 Undocumented weak
references
– Bindings.bindContent()
– Bindings.bindBidirectional()
 ”Living in the future”
Tips for starting with JavaFX 2
 Run tests early on all platforms that you will
support.
 Learn and use CSS and FXML.
 Use IntelliJ IDEA or NetBeans.
 Prepare mentally to move to JavaFX 8.
 You’re not a UX designer.
 Enjoy!
– JavaFX is cool, fun and here to stay.
Session Overview
 Introduction
 Our experiences
– Why we chose JavaFX
– How we use JavaFX
– The great migration
– Pros, cons and tips
 Examples of JavaFX usage
 Our tools
– GuavaFX
– TestFX
EXAMPLES OF JAVAFX USAGE
Session Overview
 Introduction
 Our experiences
– Why we chose JavaFX
– How we use JavaFX
– The great migration
– Pros, cons and tips
 Examples of JavaFX usage
 Our tools
– GuavaFX
– TestFX
GUAVAFX
What is GuavaFX?
 Functional extensions for
the ObservableList, inspired by Google Guava.
– transform
– filter
– concat (preserves ordering)
 Game changer for us.
 Cached.
 Using weak listeners.

THE LOADUI CANVAS
GuavaFX Case Study:
ObservableList<ComponentNode> components =
transform(canvas.getComponents(), componentToNode);
bindContent(componentLayer.getChildren(), components);
ObservableList<WireNode> wires = transform(canvas.getWires(), wireToNode);
bindContent(wireLayer.getChildren(), wires);
ObservableList<Template> scenarioTemplates = ofServices(ScenarioTemplate.class);
ObservableList<Template> componentTemplates = ofServices(ComponentTemplate.class)
.filter(notDeprecated);
ObservableList<TemplateNode> toolboxItems =
concat(scenarioTemplates, componentTemplates).transform(templateToNode);
bindContent(toolbox.getItems(), toolboxItems);
Code in plain JavaFX
final ObservableList<ComponentNode> components = observableArrayList();
components.addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
componentLayer.getChildren().clear();
for( Component component : components ) {
componentLayer.getChildren().add(componentToView(component));
}
}
});
final ObservableList<WireNode> wires = observableArrayList();
wires.addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
wireLayer.getChildren().clear();
for( Wire wire : wires ) {
wireLayer.getChildren().add( wireToView( wire ) );
}
}
});
ObservableList<Descriptor> scenarioDescriptors =
ofServices(ScenarioDescriptor.class);
ObservableList<Descriptor> componentDescriptorsUnfiltered =
ofServices(ComponentDescriptor.class);
final ObservableList<Descriptor> componentDescriptors =
observableArrayList();
componentDescriptorsUnfiltered.addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
componentDescriptorsUnfiltered.getChildren().clear();
for( Descriptor descriptor : componentDescriptorsUnfiltered ) {
if( descriptor.isDeprecated() ) {
componentDescriptors.getChildren().add( descriptor );
}
}
}
});
final ObservableList<ToolBoxItem> toolboxItems = observableArrayList();
InvalidationListener concatListener = new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
toolboxItems.getChildren().clear();
for( Descriptor descriptor : componentDescriptorsUnfiltered ) {
toolboxItems.getChildren().add(descriptorToView(descriptor));
}
for( Descriptor descriptor : scenarioDescriptors ) {
toolboxItems.getChildren().add(descriptorToView(descriptor));
}
}
}
componentDescriptors.addListener(concatListener);
scenarioDescriptors.addListener(concatListener);
• Also has to remove all InvalidationListeners
when no longer needed.
• Performance is worse (no caching).
JavaFX 8
 Current state:
– ObservableList.filtered
– ObservableList.sorted
– No ObservableList.transformed
 Will hopefully make GuavaFX obsolete.
myObservableList.filtered(tweet -> tweet.isRetweet())
TESTFX
Why TestFX?
 We needed:
– Tests that any tester could follow and modify.
 Options:
– JemmyFX was too complicated and verbose.
– FEST-JavaFX was dead.
– MarvinFX didn’t yet exist.
– No GUI testing software existed for JavaFX.
– Write our own!
What is TestFX?
 A fluent and fixture-less API for interacting with
JavaFX applications:
– rightClick("#desktop").moveMouseTo("New")
.click("Text Document")
.type("myTextfile.txt")
.press(ENTER)
– drag(myNode).to("#trash-can")
– press(CONTROL, A)
What is TestFX?
 ...and verifying JavaFX applications’ behavior:
– assertThat("My folder", contains(3, ".file"))
– clickNodeThat(hasLabel(endsWith("FX")))
– waitUntil(continueButton, is(enabled()))

Key principles
 Fixture-less
– Don’t have to create fixtures for custom controls
– Clean code that most testers can read
– Enables TDD
– Dangerous?
/** It is always dangerous to directly access objects within Java
FX hierarchy. All the access should be done through event queue.
If done otherwise results are unpredictable at the best. */
• Not in our experience.
 60 tests running for more than a year.
 Stress test to provoke JavaFX/TestFX.
» Using Timeline, bindings and millisecond precision
assertions.
Key principles
 Hamcrest Matchers
– Makes use of regular Hamcrest Matchers.
– Provides a few JavaFX specific Matchers.
 States
– Optional
JemmyFX official example
@Test
public void hello() {
SceneDock scene = new SceneDock();
ListViewDock list = new ListViewDock(scene.asParent());
final TextInputControlDock address = new TextInputControlDock(scene.asParent());
String location = address.getText();
address.asSelectionText().to(address.getText().length());
address.type("testdata");
address.keyboard().pushKey(ENTER);
new ListItemDock(list.asList(), new LookupCriteria() {
@Override
public boolean check(Object cntrl) {
return cntrl.toString().endsWith("folder1");
}
}).mouse().click(2);
new ComboBoxDock(scene.asParent()).asSelectable().selector().select(new File(location));
address.wrap().waitProperty(Wrap.TEXT_PROP_NAME, location);
new LabeledDock(scene.asParent(), "back_btn").mouse().click();
new ListItemDock(list.asList(), "file.txt", SUBSTRING).mouse().click(1);
}
Same example in TestFX
@Test
public void hello() {
click("#address-field").type("testdata").press(ENTER);
doubleClick("folder1");
click(".combo-box").click("Tests");
click("#back_btn").click("file.txt");
}
...with some Hamcrest matchers
@Test
public void hello() {
click("#address-field").type("testdata").press(ENTER);
doubleClick("folder1");
click(".combo-box").click("Tests");
click("#back_btn").click("file.txt");
assertThat("#directory-listing", contains(1, ".file"));
assertThat("#directory-listing .file", hasLabel("file.txt"));
}
How we use TestFX
 GUI unit tests
class MyTest extends GuiTest {
@BeforeClass
public static void createStage() {
showNodeInStage( nodeUnderTest );
}
@Test
public static void nodeUnderTest_should_behave() {
// Test logic goes here.
}
}
How we use TestFX
 System tests
– With states (TestState.java).
• First state starts LoadUI.
System Tests
LoadUI Started
Notification
PanelTest
System
LogTest
ProjectCreated
AgentsCreated MonitorTest
Project
ManagementTest
ProjectLoaded
TableLog
Test
EventHandling
Test
Execution
Test
Result
ViewTest
LastResult
Opened
Statistic
TabsTest
WireTest
Linked
PlaybackTest
SimpleScenario
ChartCompare
Test
ChartsTest
PlaybackTest
Last slide
 Links
– loadui.org
– github.com/SmartBear/loadui
– github.com/SmartBear/GuavaFX
– github.com/SmartBear/TestFX
– miglayout.com
 Thanks to
– Dain Nilsson
– Ole Lensmar
– Sofia Stråth
– LoadUI contributors
– SmartBear Stockholm
smartbear.com/careers
Q & A

More Related Content

What's hot

Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010JUG Lausanne
 
Jenkins Evolutions - JEEConf 2012
Jenkins Evolutions - JEEConf 2012Jenkins Evolutions - JEEConf 2012
Jenkins Evolutions - JEEConf 2012Anton Arhipov
 
vJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemAndres Almiray
 
How the JDeveloper team test JDeveloper at UKOUG'08
How the JDeveloper team test JDeveloper at UKOUG'08How the JDeveloper team test JDeveloper at UKOUG'08
How the JDeveloper team test JDeveloper at UKOUG'08kingsfleet
 
Building Quality with Foundations of Mud
Building Quality with Foundations of MudBuilding Quality with Foundations of Mud
Building Quality with Foundations of Mudseleniumconf
 
Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"
Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"
Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"Fwdays
 
KraQA #29 - Component level testing of react app, using enzyme
KraQA #29 - Component level testing of react app, using enzymeKraQA #29 - Component level testing of react app, using enzyme
KraQA #29 - Component level testing of react app, using enzymekraqa
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideMek Srunyu Stittri
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015jbandi
 
Node.JS error handling best practices
Node.JS error handling best practicesNode.JS error handling best practices
Node.JS error handling best practicesYoni Goldberg
 
Stop (de)bugging me - ICON UK 2013
Stop (de)bugging me - ICON UK 2013Stop (de)bugging me - ICON UK 2013
Stop (de)bugging me - ICON UK 2013Mark Leusink
 
JavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaJavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaChristopher Bartling
 
Better Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternBetter Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternSQALab
 
Test-Driven JavaScript Development (JavaZone 2010)
Test-Driven JavaScript Development (JavaZone 2010)Test-Driven JavaScript Development (JavaZone 2010)
Test-Driven JavaScript Development (JavaZone 2010)Christian Johansen
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF SummitOrtus Solutions, Corp
 
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016Gavin Pickin
 
Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"
Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"
Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"Fwdays
 

What's hot (20)

Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
Java EE 6 & GlassFish V3 - Alexis Moussine-Pouchkine - May 2010
 
Jenkins Evolutions - JEEConf 2012
Jenkins Evolutions - JEEConf 2012Jenkins Evolutions - JEEConf 2012
Jenkins Evolutions - JEEConf 2012
 
Unit testing - A&BP CC
Unit testing - A&BP CCUnit testing - A&BP CC
Unit testing - A&BP CC
 
vJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX Ecosystem
 
How the JDeveloper team test JDeveloper at UKOUG'08
How the JDeveloper team test JDeveloper at UKOUG'08How the JDeveloper team test JDeveloper at UKOUG'08
How the JDeveloper team test JDeveloper at UKOUG'08
 
Building Quality with Foundations of Mud
Building Quality with Foundations of MudBuilding Quality with Foundations of Mud
Building Quality with Foundations of Mud
 
Unit testing hippo
Unit testing hippoUnit testing hippo
Unit testing hippo
 
Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"
Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"
Михаил Боднарчук "Acceptance Testing in NodeJS: Tools & Approaches"
 
KraQA #29 - Component level testing of react app, using enzyme
KraQA #29 - Component level testing of react app, using enzymeKraQA #29 - Component level testing of react app, using enzyme
KraQA #29 - Component level testing of react app, using enzyme
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java side
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015
 
Node.JS error handling best practices
Node.JS error handling best practicesNode.JS error handling best practices
Node.JS error handling best practices
 
Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Stop (de)bugging me - ICON UK 2013
Stop (de)bugging me - ICON UK 2013Stop (de)bugging me - ICON UK 2013
Stop (de)bugging me - ICON UK 2013
 
JavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaJavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and Karma
 
Better Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternBetter Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component Pattern
 
Test-Driven JavaScript Development (JavaZone 2010)
Test-Driven JavaScript Development (JavaZone 2010)Test-Driven JavaScript Development (JavaZone 2010)
Test-Driven JavaScript Development (JavaZone 2010)
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
 
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
 
Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"
Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"
Сергей Больщиков "Angular Components: все уже за, а вы еще нет?"
 

Viewers also liked

SEO for Publishing
SEO for PublishingSEO for Publishing
SEO for PublishingJohn Doherty
 
20090502 oecd tertiary-review_china
20090502 oecd tertiary-review_china20090502 oecd tertiary-review_china
20090502 oecd tertiary-review_chinaLichia Saner-Yiu
 
Ontologies and Similarity
Ontologies and SimilarityOntologies and Similarity
Ontologies and SimilaritySteffen Staab
 
CIPR Reputation Management Workshop on Corporate Blogging
CIPR Reputation Management Workshop on Corporate BloggingCIPR Reputation Management Workshop on Corporate Blogging
CIPR Reputation Management Workshop on Corporate BloggingStephen Waddington
 
Secrets of a Great Presentation
Secrets of a Great PresentationSecrets of a Great Presentation
Secrets of a Great PresentationJohn Wm. Watson
 
Покрывая мили на пути к Миллениуму; Introduction of the XO in Russia
Покрывая мили на пути к Миллениуму; Introduction of the XO in RussiaПокрывая мили на пути к Миллениуму; Introduction of the XO in Russia
Покрывая мили на пути к Миллениуму; Introduction of the XO in RussiaHarrie Vollaard
 

Viewers also liked (7)

SEO for Publishing
SEO for PublishingSEO for Publishing
SEO for Publishing
 
20090502 oecd tertiary-review_china
20090502 oecd tertiary-review_china20090502 oecd tertiary-review_china
20090502 oecd tertiary-review_china
 
Ontologies and Similarity
Ontologies and SimilarityOntologies and Similarity
Ontologies and Similarity
 
CIPR Reputation Management Workshop on Corporate Blogging
CIPR Reputation Management Workshop on Corporate BloggingCIPR Reputation Management Workshop on Corporate Blogging
CIPR Reputation Management Workshop on Corporate Blogging
 
Secrets of a Great Presentation
Secrets of a Great PresentationSecrets of a Great Presentation
Secrets of a Great Presentation
 
EHRs, PHR
EHRs, PHREHRs, PHR
EHRs, PHR
 
Покрывая мили на пути к Миллениуму; Introduction of the XO in Russia
Покрывая мили на пути к Миллениуму; Introduction of the XO in RussiaПокрывая мили на пути к Миллениуму; Introduction of the XO in Russia
Покрывая мили на пути к Миллениуму; Introduction of the XO in Russia
 

Similar to Ten Man-Years of JavaFX: Real World Project Experiences

Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Libraryjeresig
 
Presentations Unusual Java Bugs And Detecting Them Using Foss Tools
Presentations Unusual Java Bugs And Detecting Them Using Foss ToolsPresentations Unusual Java Bugs And Detecting Them Using Foss Tools
Presentations Unusual Java Bugs And Detecting Them Using Foss ToolsGanesh Samarthyam
 
Java Fx Ajaxworld Rags V1
Java Fx Ajaxworld Rags V1Java Fx Ajaxworld Rags V1
Java Fx Ajaxworld Rags V1rajivmordani
 
Building JBoss AS 7 for Fedora
Building JBoss AS 7 for FedoraBuilding JBoss AS 7 for Fedora
Building JBoss AS 7 for Fedorawolfc71
 
Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Alex Motley
 
Smart Client Development
Smart Client DevelopmentSmart Client Development
Smart Client DevelopmentTamir Khason
 
JavaFX - Sketch Board to Production
JavaFX - Sketch Board to ProductionJavaFX - Sketch Board to Production
JavaFX - Sketch Board to ProductionYoav Aharoni
 
Java Course 15: Ant, Scripting, Spring, Hibernate
Java Course 15: Ant, Scripting, Spring, HibernateJava Course 15: Ant, Scripting, Spring, Hibernate
Java Course 15: Ant, Scripting, Spring, HibernateAnton Keks
 
Dynamic Groovy Edges
Dynamic Groovy EdgesDynamic Groovy Edges
Dynamic Groovy EdgesJimmy Ray
 
Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...
Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...
Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...Peter Pilgrim
 
Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applicationshchen1
 
Oscon2007 Windmill
Oscon2007 WindmillOscon2007 Windmill
Oscon2007 Windmilloscon2007
 
Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...
Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...
Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...Cωνσtantίnoς Giannoulis
 
Ajax Tutorial
Ajax TutorialAjax Tutorial
Ajax Tutorialoscon2007
 
Concurrency in Eclipse: Best Practices and Gotchas
Concurrency in Eclipse: Best Practices and GotchasConcurrency in Eclipse: Best Practices and Gotchas
Concurrency in Eclipse: Best Practices and Gotchasamccullo
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaWO Community
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017Ayush Sharma
 
Golang @ Tokopedia
Golang @ TokopediaGolang @ Tokopedia
Golang @ TokopediaQasim Zaidi
 

Similar to Ten Man-Years of JavaFX: Real World Project Experiences (20)

Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Library
 
Presentations Unusual Java Bugs And Detecting Them Using Foss Tools
Presentations Unusual Java Bugs And Detecting Them Using Foss ToolsPresentations Unusual Java Bugs And Detecting Them Using Foss Tools
Presentations Unusual Java Bugs And Detecting Them Using Foss Tools
 
Java Fx Ajaxworld Rags V1
Java Fx Ajaxworld Rags V1Java Fx Ajaxworld Rags V1
Java Fx Ajaxworld Rags V1
 
Building JBoss AS 7 for Fedora
Building JBoss AS 7 for FedoraBuilding JBoss AS 7 for Fedora
Building JBoss AS 7 for Fedora
 
Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)
 
Smart Client Development
Smart Client DevelopmentSmart Client Development
Smart Client Development
 
JavaFX - Sketch Board to Production
JavaFX - Sketch Board to ProductionJavaFX - Sketch Board to Production
JavaFX - Sketch Board to Production
 
Java Course 15: Ant, Scripting, Spring, Hibernate
Java Course 15: Ant, Scripting, Spring, HibernateJava Course 15: Ant, Scripting, Spring, Hibernate
Java Course 15: Ant, Scripting, Spring, Hibernate
 
Dynamic Groovy Edges
Dynamic Groovy EdgesDynamic Groovy Edges
Dynamic Groovy Edges
 
Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...
Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...
Devoxx UK 2013 Test-Driven Development with JavaEE 7, Arquillian and Embedded...
 
Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applications
 
Oscon2007 Windmill
Oscon2007 WindmillOscon2007 Windmill
Oscon2007 Windmill
 
Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...
Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...
Lessons Learned in Software Development: QA Infrastructure – Maintaining Rob...
 
Ajax Tutorial
Ajax TutorialAjax Tutorial
Ajax Tutorial
 
Concurrency in Eclipse: Best Practices and Gotchas
Concurrency in Eclipse: Best Practices and GotchasConcurrency in Eclipse: Best Practices and Gotchas
Concurrency in Eclipse: Best Practices and Gotchas
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with Scala
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017
 
Java7
Java7Java7
Java7
 
Golang @ Tokopedia
Golang @ TokopediaGolang @ Tokopedia
Golang @ Tokopedia
 
Core Java
Core JavaCore Java
Core Java
 

Recently uploaded

New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 

Recently uploaded (20)

New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 

Ten Man-Years of JavaFX: Real World Project Experiences

  • 1. Ten Man-Years of JavaFX: Real World Project Experiences JavaZone 2013 Henrik Olsson @imheols
  • 2. Session Overview  Our experiences – Why we chose JavaFX – How we use JavaFX – The great migration – Pros, cons and tips  Examples of JavaFX usage  Our tools – GuavaFX – TestFX  Introduction
  • 3. About me  Developer and Product Owner of LoadUI – SmartBear Software in Stockholm  Worked with JavaFX for ~3 years  Contact – henrik.olsson@smartbear.com – linkedin.com/in/heols  This is my first conference session
  • 4. LoadUI  Open Source load testing tool.  Sister application of SoapUI.
  • 5. Session Overview  Our experiences – Why we chose JavaFX – How we use JavaFX – The great migration – Pros, cons and tips  Examples of JavaFX usage  Our tools – GuavaFX – TestFX  Introduction
  • 6.
  • 7.
  • 9. GUI as a Competitive Advantage
  • 11. “JavaFX 1 will reach end of life (EOL) in December.” The JavaFX Blog, Spring 2012 “We can’t finish the migration of LoadUI until early next year. Will we be able to redistribute our existing LoadUI versions after the EOL date?” SmartBear Sweden CTO, February 2012 “No, sorry.” Oracle Representative in a phone call, February 2012
  • 12. “Several software engineers have warned against total rewrites, especially under schedule constraints or competitive pressures.” From Rewrite (programming) at Wikipedia
  • 13. The JavaFX Blog, May 2013 “We've decided to create a workaround that will allow anyone to redistribute the JavaFX 1 Runtime. This solution is available today…” “The EOL is postponed to March 2013. Redistribution of the JavaFX 1 Runtime is not an option, for a number of reasons.” Oracle Representative, Fall of 2012 “The deadline will be very hard to meet. Is it possible to delay the EOL, or let us redistribute the JavaFX 1 Runtime?” Me, Fall of 2012 “We are done with the migration!” Me, April 2013
  • 14. Migrating  41k lines of JavaFX 1 (JavaFX Script) to 32k lines of JavaFX 2 (Java). – In 9 months  JavaFX 1 and JavaFX 2 cannot co-exist.  All code isolated in an OSGi module.  More of a rewrite than a migration.
  • 16. JavaFX 1 Good stuff  Flexible  CSS  Fun! Pitfalls  Poor IDE support  Hard to debug  License issues  Missing basic controls
  • 17. JavaFX 2 Good stuff  Flexible  CSS  Fun! Pitfalls  Poor IDE support  Hard to debug  License issues  Missing basic controls  FXML – MVC for real!  Multi-platform issues  Undocumented weak references – Bindings.bindContent() – Bindings.bindBidirectional()  ”Living in the future”
  • 18. Tips for starting with JavaFX 2  Run tests early on all platforms that you will support.  Learn and use CSS and FXML.  Use IntelliJ IDEA or NetBeans.  Prepare mentally to move to JavaFX 8.  You’re not a UX designer.  Enjoy! – JavaFX is cool, fun and here to stay.
  • 19. Session Overview  Introduction  Our experiences – Why we chose JavaFX – How we use JavaFX – The great migration – Pros, cons and tips  Examples of JavaFX usage  Our tools – GuavaFX – TestFX
  • 21. Session Overview  Introduction  Our experiences – Why we chose JavaFX – How we use JavaFX – The great migration – Pros, cons and tips  Examples of JavaFX usage  Our tools – GuavaFX – TestFX
  • 23. What is GuavaFX?  Functional extensions for the ObservableList, inspired by Google Guava. – transform – filter – concat (preserves ordering)  Game changer for us.  Cached.  Using weak listeners. 
  • 25.
  • 26. ObservableList<ComponentNode> components = transform(canvas.getComponents(), componentToNode); bindContent(componentLayer.getChildren(), components);
  • 27. ObservableList<WireNode> wires = transform(canvas.getWires(), wireToNode); bindContent(wireLayer.getChildren(), wires);
  • 28. ObservableList<Template> scenarioTemplates = ofServices(ScenarioTemplate.class); ObservableList<Template> componentTemplates = ofServices(ComponentTemplate.class) .filter(notDeprecated); ObservableList<TemplateNode> toolboxItems = concat(scenarioTemplates, componentTemplates).transform(templateToNode); bindContent(toolbox.getItems(), toolboxItems);
  • 29. Code in plain JavaFX final ObservableList<ComponentNode> components = observableArrayList(); components.addListener(new InvalidationListener() { @Override public void invalidated(Observable observable) { componentLayer.getChildren().clear(); for( Component component : components ) { componentLayer.getChildren().add(componentToView(component)); } } }); final ObservableList<WireNode> wires = observableArrayList(); wires.addListener(new InvalidationListener() { @Override public void invalidated(Observable observable) { wireLayer.getChildren().clear(); for( Wire wire : wires ) { wireLayer.getChildren().add( wireToView( wire ) ); } } }); ObservableList<Descriptor> scenarioDescriptors = ofServices(ScenarioDescriptor.class); ObservableList<Descriptor> componentDescriptorsUnfiltered = ofServices(ComponentDescriptor.class); final ObservableList<Descriptor> componentDescriptors = observableArrayList(); componentDescriptorsUnfiltered.addListener(new InvalidationListener() { @Override public void invalidated(Observable observable) { componentDescriptorsUnfiltered.getChildren().clear(); for( Descriptor descriptor : componentDescriptorsUnfiltered ) { if( descriptor.isDeprecated() ) { componentDescriptors.getChildren().add( descriptor ); } } } }); final ObservableList<ToolBoxItem> toolboxItems = observableArrayList(); InvalidationListener concatListener = new InvalidationListener() { @Override public void invalidated(Observable observable) { toolboxItems.getChildren().clear(); for( Descriptor descriptor : componentDescriptorsUnfiltered ) { toolboxItems.getChildren().add(descriptorToView(descriptor)); } for( Descriptor descriptor : scenarioDescriptors ) { toolboxItems.getChildren().add(descriptorToView(descriptor)); } } } componentDescriptors.addListener(concatListener); scenarioDescriptors.addListener(concatListener); • Also has to remove all InvalidationListeners when no longer needed. • Performance is worse (no caching).
  • 30. JavaFX 8  Current state: – ObservableList.filtered – ObservableList.sorted – No ObservableList.transformed  Will hopefully make GuavaFX obsolete. myObservableList.filtered(tweet -> tweet.isRetweet())
  • 32. Why TestFX?  We needed: – Tests that any tester could follow and modify.  Options: – JemmyFX was too complicated and verbose. – FEST-JavaFX was dead. – MarvinFX didn’t yet exist. – No GUI testing software existed for JavaFX. – Write our own!
  • 33. What is TestFX?  A fluent and fixture-less API for interacting with JavaFX applications: – rightClick("#desktop").moveMouseTo("New") .click("Text Document") .type("myTextfile.txt") .press(ENTER) – drag(myNode).to("#trash-can") – press(CONTROL, A)
  • 34. What is TestFX?  ...and verifying JavaFX applications’ behavior: – assertThat("My folder", contains(3, ".file")) – clickNodeThat(hasLabel(endsWith("FX"))) – waitUntil(continueButton, is(enabled())) 
  • 35. Key principles  Fixture-less – Don’t have to create fixtures for custom controls – Clean code that most testers can read – Enables TDD – Dangerous? /** It is always dangerous to directly access objects within Java FX hierarchy. All the access should be done through event queue. If done otherwise results are unpredictable at the best. */ • Not in our experience.  60 tests running for more than a year.  Stress test to provoke JavaFX/TestFX. » Using Timeline, bindings and millisecond precision assertions.
  • 36. Key principles  Hamcrest Matchers – Makes use of regular Hamcrest Matchers. – Provides a few JavaFX specific Matchers.  States – Optional
  • 37. JemmyFX official example @Test public void hello() { SceneDock scene = new SceneDock(); ListViewDock list = new ListViewDock(scene.asParent()); final TextInputControlDock address = new TextInputControlDock(scene.asParent()); String location = address.getText(); address.asSelectionText().to(address.getText().length()); address.type("testdata"); address.keyboard().pushKey(ENTER); new ListItemDock(list.asList(), new LookupCriteria() { @Override public boolean check(Object cntrl) { return cntrl.toString().endsWith("folder1"); } }).mouse().click(2); new ComboBoxDock(scene.asParent()).asSelectable().selector().select(new File(location)); address.wrap().waitProperty(Wrap.TEXT_PROP_NAME, location); new LabeledDock(scene.asParent(), "back_btn").mouse().click(); new ListItemDock(list.asList(), "file.txt", SUBSTRING).mouse().click(1); }
  • 38. Same example in TestFX @Test public void hello() { click("#address-field").type("testdata").press(ENTER); doubleClick("folder1"); click(".combo-box").click("Tests"); click("#back_btn").click("file.txt"); }
  • 39. ...with some Hamcrest matchers @Test public void hello() { click("#address-field").type("testdata").press(ENTER); doubleClick("folder1"); click(".combo-box").click("Tests"); click("#back_btn").click("file.txt"); assertThat("#directory-listing", contains(1, ".file")); assertThat("#directory-listing .file", hasLabel("file.txt")); }
  • 40. How we use TestFX  GUI unit tests class MyTest extends GuiTest { @BeforeClass public static void createStage() { showNodeInStage( nodeUnderTest ); } @Test public static void nodeUnderTest_should_behave() { // Test logic goes here. } }
  • 41. How we use TestFX  System tests – With states (TestState.java). • First state starts LoadUI.
  • 42. System Tests LoadUI Started Notification PanelTest System LogTest ProjectCreated AgentsCreated MonitorTest Project ManagementTest ProjectLoaded TableLog Test EventHandling Test Execution Test Result ViewTest LastResult Opened Statistic TabsTest WireTest Linked PlaybackTest SimpleScenario ChartCompare Test ChartsTest PlaybackTest
  • 43. Last slide  Links – loadui.org – github.com/SmartBear/loadui – github.com/SmartBear/GuavaFX – github.com/SmartBear/TestFX – miglayout.com  Thanks to – Dain Nilsson – Ole Lensmar – Sofia Stråth – LoadUI contributors – SmartBear Stockholm smartbear.com/careers
  • 44. Q & A

Editor's Notes

  1. From a user survey.Users have started to expect well thought-out GUIs. Blame the iPhone ;-)
  2. *click *JavaFX 1 had a licensing model that prohibited redistribution of the JARs. We solved this by using Java Web Start, that fetched the JARs on the first startup.[Shorten these quotes further]
  3. *3 clicks *...and guess what happened one month later?*click*
  4. I asked people that’s been working with LoadUi over the years.Fun:Almost everybody says this! More modern than Swing and.Poor IDE support:Because of JavaFX Script.Hard to debug:Because of JavaFX Script + Not Open Source.License issues:Not allowed to redistribute the runtime.Missing basic controls:No table view, no modal windows, etc.
  5. FXML:MVC in Swing is hard. In JavaFX it’s natural.Multi-platform issues:Major problems on Windows Server. Mac problems (runs in headless mode which kills all Swing integration). Major drag-n-drop bug in Linux. All these are reportedly fixed in JavaFX 8.Living in the future:A lot of bugs are being fixed... In JavaFX 8, which already been delayed once. No backports.Things are still changing a lot: In JavaFX 2, there are builder classes for everything. In JavaFX 8, those will be removed.
  6. You’re not a UX designer:In JavaFX you can easily create new controls, with shadows, drag and drop and reflections.It’s easy to go overboard, break conventions, and create stuff with bad usability.
  7. I’m going to show how we use a few JavaFX components in LoadUI. This is probably the most interesting if you’ve been using JavaFX.Webview, med custom starterpage som öppnar youtubevideoninline. Charts, with old test-run.Tabs CSS repeating background
  8. [Explain what the LoadUI canvas is]