JavaFXComposerNewInM8

Contents

New Data Source API

To simplify access to data coming from various sources in various formats we have unified the data format on client side so that it is easier for people to start using a remote data source. There are two basic aspects of each data source:

  • actual source of data (HTTP server, database, file, etc.)
  • format of data (XML, JSON, etc.).

JavaFX Composer data source framework defines a specialized DataSource class for each source of data (HttpDataSource, FileDataSource, etc.) and defines set of parsers for each supported data format (Parsers.XML_PARSER, etc.)

When a DataSource object retries the data, it typically passes the raw stream to a Parser which understand the format and which produces a sequence of Records, a common data format in JavaFX Composer. You will learn more about this structure later in this chapter.

To summarize, common data source framework consists of three fundamental entities (classes):

  • DataSource - responsible for fetching raw data from the source
  • Parser - responsible for parsing raw data and producing Records
  • Record - a named structure holding three elements: a single value, set of attributes (name->value pairs) and child Records (if any)

Data Source

A Data Source object holds basic properties needed to fetch data from a source. For example, for HTTP Data Source this is URL, Authentication method, etc. For JDBC Data Source this is a connection string, credentials and SQL query. For File Data Source this is a file path.

See the following table for an overview of JavaFX Composer supported data sources.

Name Class Supported Data Formats Description
HTTP HttpDataSource XML, JSON, LINE, PROPERTIES fetches data from HTTP and HTTPS servers. Supports BASIC authentication.
JDBC DbDataSource SQL Table fetches data from a JDBC compliant database by executing an SQL query
File FileDataSource XML, JSON, LINE, PROPERTIES reads a file on the local filesystem
JavaFx Storage StorageDataSource XML, JSON, LINE, PROPERTIES uses javafx.io.Storage API to load data
Resources ClasspathDataSource XML, JSON, LINE, PROPERTIES reads data from runtime classpath using java Classloader.getResourceAsStream

Example Usage: Create a DataSource

var ds = FileDataSource {
    autoRefresh: false
    path: "/home/johny/bookstore.xml"
    parser: Parsers.XML_PARSER
};

This will create a datasource that will read and parse the content of the file "/home/johny/bookstore.xml". XML parser will be used.

Example Usage: Get data from a DataSource

var rs : Record [];
rs = ds.getData();
var first = rs[0];

rs now holds a sequence of Records. You can also access Records in a cursor-like way by calling:

var r : Record;
r = ds.current();
ds.next();
r = ds.current();

Remember that a DataSource maintains a cursor over its Records and initially the cursor points to the first Record. Once you have a Record, you can get to the data:

var str : String;
str = r.getAttrString("bookName");
var val = r.getValue();
var children = r.getChildren();

This will set str to the content of the attribute "bookName", val to the value of the current Record and children to sequence of child Records.

Cursors

In pre-M8 API the cursor was maintained in a special RecordSet object, now cursor methods are available directly on a DataSource. You can either call getData() to get all data at once or use cursors to access data sequentially. The latter is more appropriate for accessing large sets of data without having to load them all into memory. JDBC data source directly supports this usecase via its lazyLoading property. Cursor API has the following methods:

  • next() - moves the cursor to the next Record
  • prev() - moves the cursor to the previous Record
  • hasNext() - returns true if there is a next Record
  • hasPrev() - returns true if there is a previous Record
  • current() - retrieves the current Record under the cursor
  • currentIndex() - retrieves the index of the current Record
  • setCurrentIndex() - sets the index of the current Record (random access, may be slow)
  • close() - should be called where you are finished with the cursor

Record

Each Record has a name and holds three elements:

  • a value
  • set of attributes (name=>value pairs)
  • child Records

For example, in JDBC data source each row in a table becomes a Record with column names as attribute keys. When parsing XML, each element becomes a separate Record. In JSON, each object is transformed to a Record. Here are some examples of getting data from a record:

var r : Record; // the first book in a book store
r = ds.current();

var name : String;
name = r.getAttrString("bookName");

var authors : Record[];
authors = r.getAttr("authors") as Record[];

var storeLocation : Record;
storeLocation = r.getAttr("location") as Record;

Notice that Records can have attributes of type Record [] and Record, creating a tree-like structure.

Location

Location is a new concept in M8 API and defines a precise location of a particular data or value, it's like a pointer to a variable. Once you have a Location you simply get and set the value it points to by calling get() and set() method on the Location object which makes sure the appropriate Record's attribute is accessed. You can get a Location object by calling Record.getLocation(locationSpec: String) method. The locationSpec string has two parts:

  • a filter specification (see previous paragraph) that locates a Record
  • an attribute specification; can be empty in which case the Location will point to the Records' direct value, rather that one of its attributes' value

Here are examples of location specifications:

  • /bookstore/address/#zip - "/bookstore/address" navigates to the "address" Record and "#zip" selects the "zip" attribute of the "address" Record
  • /rss/channel/title - "/rss/channel/title" navigates to the "title" Record and since there is no attribute specification the Location will get/set the value of the "title" Record

Write Support

Unlike in the previous API version, every Record is now read/write. Attributes of a Record can be modified using the setAttr() method and its value can be changed with the setValue() method. Even more convenient is to get a Location object for the value you want to work with (read and/or modify) and use get() and set() methods on the Location object. All changes are propagated to the original Record. Whenever data in a Record change, the Record is marked dirty, see the next paragraph.

Dirty Flag

When a Record is modified it is marked dirty and all its parent Records are marked dirty as well. Dirty flag is a synthetic attribute of a Record and can be read and written by getDirty() and setDirty() methods. Calling setDirty(true) marks all parents dirty and setDirty(false) marks all descendants clean. You can check the dirty flag to see whether it is necessary to commit changes i.e. synchronize in-memory data with the original data source.

Data Source Components

The old-version data sources has been deprecated and the new-version data sources become the primary.

In the Palette, the old data sources has been moved to "Data Sources (deprecated)" category. A new "Data Source" category has been added to the Palette and contains new versions of the data sources.

file:javafx-composer-newinm8-datasource-palette.png

The UI and work-flow remain the same as for the old-version data sources i.e. you can drag and drop them to your design, customize them and use them in the Bind mode of a Details Property Editor window.

The new customizer looks the same as before. It just represents the structure of the data parsed by a DataSource/Parser.

file:javafx-composer-newinm8-datasource-customizer.png

Similarly when you working with sub-data-sources. The "Add Data Source" dialog just pre-fill a filter expression matching to the new data structure and new filter syntax.

file:javafx-composer-newinm8-datasource-filter.png

In the Bind mode of a Details Property Editor window there are new converters added to support the new the Data Source API.

file:javafx-composer-newinm8-datasource-bind.png

Data Source Controls

The new Data Source API allowed creation of ease-to use/bind Controls. There is a new "Data Source Controls" category in the Palette.

file:javafx-composer-newinm8-controls-palette.png

When you drag and drop the controls from the category in the Palette and place them to the Design editor or in Navigator. When dropped a message dialog shown to notify you that necessary files has been generated to your project (in the "org.netbeans.javafx.data.control" package).

These Data Source aware controls are inherited from they standard counterpart from JavaFX 1.3.1 SDK. Additionally they have properties located into a new (opened by default) "Data Source" category in the Properties window. The new properties allows you to easily customize and connect to a data source.

file:javafx-composer-newinm8-controls-properties.png

DSListView

This control renders a sequence of Records using ListView control. There are the following properties available:

  • DataSource - select a data source to connect to
  • Filter - optionally specify a filter expression to filter the results e.g. "@project"
  • Converter - a function that allows to convert/customize the found sequence of Records
  • Renderer - a function that returns a String value from each Record that should be renderer in the ListView; you can still use cell-factory to override the default behavior (which uses Renderer function) and use your own custom cell factory

Additionally the DSListView control contains itemsDataSource variable which can be uses as a data-source for other "child" components. The "itemsDataSource" represents all the Record within your ListView and additionally its "current()" Record is synchronized with the "selectedItem" in the ListView.

file:javafx-composer-newinm8-controls-dslistview.png

DSChoiceBox

Similarly to DSListView, it allows to select a single Record from a sequence of Records using ChoiceBox control.

This control has the same properties as DSListView control. The "DSChoiceBox.itemsDataSource.current()" is synchronized with the currently selected item.

file:javafx-composer-newinm8-controls-dschoicebox.png

DSTextBox

This control extends standard TextBox. It connects to a specified Location within the "current()" Record within specified Data Source. The value at that location is obtained and rendered in the text-box. If the text is modified by user, the text is stored back to the Record using Write API. There are the following properties avaiable:

  • DataSource - select a data source to connect to
  • Location - specify a location expression relatively to the "current()" Record of the specified data source
  • Converter - a function that allows to convert Object value to a String value; if not set, then the Object value is automatically converted using "toString" method; "null" value is auto-converted as empty string
  • ContinuousUpdate - if true, any modification is immediatelly process; if false, the modification is stored when Enter key is pressed in the DSTextBox.

Note for Location and Write API see the sections above.

file:javafx-composer-newinm8-controls-dstextbox.png

DSPasswordBox

Similar to DSTextBox but based on standard PasswordBox.

file:javafx-composer-newinm8-controls-dspasswordbox.png

DSLabel

Similar to DSTextBox but does not have "ContinuousUpdate" property and does not allow to user-modify the rendered value.

file:javafx-composer-newinm8-controls-dslabel.png

DSCheckBox

Similar to DSTextBox but render the Boolean value only by selecting/unselecting the check-box. There is no "ContinuousUpdate" property is the user-modification is immediately processed.

The "Converter" function allows to convert the Object value from obtained from the Location to a Boolean value used to selecting the check-box.

file:javafx-composer-newinm8-controls-dscheckbox.png

Data Validation

The new Data Source API comes with a new checking/validating/reporting control. There is a new "org.netbeans.javafx.data.control.validation" package. This package can be used without the new Data Source API.

There is a "Report Node" control in the "Data Source Controls" category in the Palette. You can drag and drop it to the Design editor. The contains a "Validators" property which allows you to specify a sequence of validators.

file:javafx-composer-newinm8-controls-reportnode.png

Validator is responsible for a particular validation and contains a type (note, warning, error) and a message that is printed in the "Report Node" in case the validation fails.

Validator class contains the following variables:

  • message - the message that should be printed if validation fails
  • type - type of MessageType enum that can be set to ERROR, WARNING or NOTE; determines an icon that should show on the left-side of the message
  • validate - bound function which takes no parameters and returns a boolean value; if true, then the validation passed; if false, then the validation failed; this function is bound to allow live-validation of your data.

Form Customizer Improvements

The Form components that been improved to support work with the new Data Source API and Controls.

You can use it to select the old-version Data Sources, List Views or new-version Data Sources as the Data Source. If you use old-version Data Sources, then the customizer works exactly as before.

If you use new-version Data Source, then there is an additional "Editable" column in the fields table used.

file:javafx-composer-newinm8-form-customizer.png

The Form customizer will automatically generate the form structure in the Design that would be use DSLabel and DSTextBox for showing value of each field. DSTextBox is used if the particular field is checked as Editable. DSLabel is used otherwise.

file:javafx-composer-newinm8-form-design.png

Design Usability Improvements

  • The behavior of image placeholder has changed, allowing user to switch between standard and placeholder view.
  • Improved and simplified guidelines to lower confusion
  • Added new handlers to allow easily move parent container if child is selected.

Code Generation of Initial Values

Code generator no more uses master values as the initial values of fields in instances initialization.

Now the initial value of a field is the value of the particular property at the start-state of an appropriate state-variable that controls the property. In case the property is not modified at any state, then the value from the master state is used as before.

A Scene component has an additional "Use Start State as Master" property that allows to control whether to use the previous or the new initial-value evaluation. If the properties is set to True then the new approach is used.

file:javafx-composer-newinm8-scene-property.png

Misc

Generated Files Update

Every time you switch to Source tab or Save a design file while there has been a modification in the design, the code in the guarded block in the source file is regenerated.

Newly additionally to that, the design is inspected for all components (Data Sources, Data Source Controls) that require additional files to generated to your project for proper work e.g. the DSLabel component requires a few files in "org.netbeans.javafx.data" package. All the additional files that are required by the used components are checked and updated if necessary to the latest version.

Palette

Some categories in the Palette are collapsed initially to improve the visibility of the important components in the Palette. Only Layouts, Controls, new Data Sources and Templates categories are expanded.

Samples

The samples has been updated to use the new Data Source API.

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo