DataFX - JavaOne 2013

of 57/57
Data FX The best way to get real-world data into your JavaFX application
  • date post

  • Category


  • view

  • download


Embed Size (px)


The best way to get real-world data into your JavaFX application

Transcript of DataFX - JavaOne 2013

  • 1.DataFXThe best way to get real-world data into your JavaFX application

2. The Mission In this session, you'll learn how to develop Enterprise Applications in JavaFX with Real-World Services and Data. We will show how the DataFX framework facilitates the process of data retrieval and rendering, and how it allows you to focus on your application-specic logic. 3. About us Hendrik Ebbers @hendrikEbbers . Johan Vos @johanvos . 4. Overview 5. Overview DataSources Websocket Cells Flow 6. Use DataFX 7. Use DataFX JSF View Browser Desktop Client Business Layer O r m aybe m obile... Server Persistence REST 8. Concurrency 9. Concurrency API JavaFX is a single threaded toolkit You should not block the platform thread Rest calls may take some time... ...and could freeze the application Do not do this at home! 10. DataFX Executor Executor executor = new ObservableExecutor(); ListView> list = new ListView(); list.setCellFactory(new ServiceCellFactory()); list.itemsProperty(). bind(executor.currentServicesProperty()); implementation ofjava.util.concurrent.Executor bind your services to the view 11. DataFX Executor supports title, message and progress for each service supports Runnable, Callable, Service & Task cancel services on the gui 12. Lets wait void ConcurrentUtils.runAndWait(Runnable runnable) T ConcurrentUtils.runAndWait(Callable callable) like SwingUtilities.invokeAndWait(...) we will collect all concurrent helper methods here 13. Lambda Support JDK 8 has Lambda and the awesome Stream API Map and reduce your collections in parallel But how to turn into the JavaFX application thread? 14. Lambda Support StreamFX streamFX = new StreamFX(myStream); it is a wrapper ObservableList list = ...; streamFX.publish(list); streamFX.forEachOrdered(final Consumer> action) this will happen in the application thread 15. DataSources 16. DataSources Obtain data from a variety of sources, in a variety of formats and put the data in a JavaFX Observable or ObservableList Object. Goal: Variety of sources -> the DataReader abstracts this Variety of formats -> the Converter abstracts this * * 1 11 * 11 * 1 17. DataSources Data Observable / ObservableList DataFX DataProvider DataReader Converter 18. DataReader interface DataReader { T get(); boolean next(); } Easy to implement! RestSource FileSource JDCBSource We provide this implementations - with builder API - 19. RestReader RestSource restSource = new RestSource(); restSource.setHost(myhost); RestSource.setConverter(...); restSource.setPath("user/" + uid); restSource.setConsumerKey(mykey); restSource.setConsumerSecret(mysecret); RestSourceBuilder.create().host(myhost) .converter(...).path(user).path(uid) .consumerKey(myKey).consumerSecret(mysecret) .build() -or- 20. Data conversion DataReader has to provide data as an object of type T Converter consumes input as U, and provides data as T 21. Converter interface Converter { public void initialize(T input); public U get(); public boolean next(); } create your custom one JSONConverter implements Converter RestSource reads an InputStream, and will ask Converter to deliver instance(s) of T 22. DataProvider DataProviders populate JavaFX Observable and ObservableList instances Data is added/changed on the JavaFX Application Thread only Retrieval is done in a background thread, managable via an ExecutorPool 23. DataProvider API distinction between ObjectDataProvider and ListDataProvider Builders are provided: ObjectDataProviderBuilder ListDataProviderBuilder 24. Usage ObservableValue dataProvider.getData(); Worker dataProvider.retrieve().getValue(); DataProvider.setResultObjectProperty(o); different patterns for different developers How to populate Observable o with the retrieved value via DataProvider dataProvider? or or 25. DataProvider DataProviders leverage the Observable capabilities: content is added when it is available ListDataProvider will add entities to the resulting ObservableList as long as input can be read from the DataReader 26. DataProvider Binding the ObservableList in a ListView will cause the ListView to be populated gradually This can be leveraged in your application logic, i.e. First retrieve the most recent or important items 27. Writeback support Starting in DataFX 2.0, it is possible to make changes to retrieved data, and send those changes back to the original datasource UI Observable external Data DataFX 28. Challenges We don't want to write-back all changes In many cases, write-back is more complex than read, and not symmetrical i.e. Authentication needed, different granularity 29. Writeback support only one additional class that handles the writeback... ObjectDataProvider.setWriteBackHandler(WriteBackHandler h); ListDataDataProvider.setAddEntryHandler(WriteBackHandler h); ...and you only need to implement one method 30. Example DataReader dr = new JdbcSource(....); ListDataProvider lodp = new ListDataProvider(dr); ObservableList myList = ...; lodp.setResultObservableList(myList); lodp.setWriteBackHandler(new WriteBackHandler() {...}); ok, this is the part we already know adding writeback support 31. Example lodp.setWriteBackHandler(new WriteBackHandler() { @Override public WritableDataReader createDataSource(Person me) { String statement = "UPDATE PERSON SET lastName='" + me.getLastName() + "' WHERE firstName='" + me.getFirstName() + "'"; JdbcSource dr = new JdbcSource(dbURL, statement, null); dr.setUpdateQuery(true); return dr; } }); simple implementation of jdbc writeback support 32. Writeback support RestSource and JDBCSource already implement WritableDataReader Threading is dealt with by DataReader implementations Support of transient eld by using @WriteTransient 33. Controller API 34. JAVAFX API In JavaFX you should use FXML to dene your views You can dene a controller for the view Link from (FXML-) view to the controller 35. Controller API Some kind of inversion of control Dene the FXML in your controller class Create a view by using the controller class Supports more annotations for the view livecycle convention over conguration 36. Controller API @FXMLController("Details.fxml") public class DetailViewController { @FXML private TextField myTextfield; @FXML private Button backButton; @PostConstruct public void init() { myTextfield.setText("Hello!"); } } define the FXML file default Java annotation 37. Controller API use JavaFX Scene Builder! no controller class is set in FXML 38. Controller API Provides a factory for view creation Inject all needed Nodes with @FXML Supports @PostConstruct 39. View Context Controller API support 2 contexts ApplicationContext View Context Inject context by using Annotation Register your model to the context 40. View Context public class DetailViewController { @FXML private TextField myTextfield; @FXMLViewContext private ViewContext context; @PostConstruct public void init() { DataModel model = context.getViewFlowContext(). getRegisteredObject(DataModel.class); myTextfield.textProperty(). bindBidirectional(model.getSelected()); } } injection access registered objects 41. Conclusion Create view with FXML Dene your model as pojo Create a controller bind all this by using annotations 42. Flow API 43. Flow API Controller API is good for one view How to link dierent view? 44. Flow API open View View View View View View searc h details open diagram setting * 45. Master Detail two views: master and detail use FXML switch from one view to the other one delete data on user action decoupling all this stu!! 46. Master Detail MasterView DetailsView back details delete 47. Master Detail MasterView DetailsView back details FXML Controller FXML Controller delete 48. Master Detail FXMLFlowView masterView = FXMLFlowView.create(MasterViewController.class); FXMLFlowView detailView = FXMLFlowView.create(DetailViewController.class); create one FLowView for each view use controller API internally MasterView DetailsView back details delete 49. Master Detail detailView.withChangeViewAction("back", masterView); direct link between the views action name MasterView DetailsView back details delete 50. Master Detail masterView.withRunAction("delete", DeleteAction.class); define a custom action action name delete MasterView DetailsView back details delete 51. Master Detail Use controller API for all views Dene a FlowView for each view link with by adding an action add custom actions to your ow but how can I use them? 52. Master Detail @FXMLController("Details.fxml") public class DetailViewController { @FXML @FlowAction("back") private Button backButton; @PostConstruct public void init() { //... } @PreDestroy public void destroy() { //... } } controller API defined in FXML bind your flow actions by annotation listen to the flow 53. Flow API share your data model by using contexts ViewFlowContext added @FXMLViewFlowContext private ViewFlowContext context; You can inject contexts in your action classes, too @PostConstruct and @PreDestroy are covered by the view livecycle 54. Flow API By using the ow API you dont have dependencies between the views Reuse views and actions Use annotations for conguration 55. more stu Websocket API Cell API FileSource 56. 57. QA