FXD Specification 1.3

FXD Format

This specification contains the following sections:

How to Use This Specification

This FXD specification can be used to write FXD descriptions of graphics that can be incorporated into JavaFX applications. This page contains an introduction to FXD format and a description of its major constructs. The navigation links in the left sidebar point to reference pages that describe each FXD element and its properties, with the exception of the FXD element, which is always used as the root element and is described below.

Except for the FXD root element, all FXD elements map onto classes of the same name in the JavaFX Script programming language, and the properties map onto JavaFX Script variables. In this specification, the page for each element shows how it maps onto the corresponding JavaFX Script class. Although FXD elements do not inherit properties, the properties on each FXD element page are classified in the same way that they map onto variables in JavaFX Script. For example, the FXD Rectangle element shows properties divided into three types: those that map onto variables in the JavaFX Script Rectangle class, and those that map onto class from which the Rectangle class inherits variables, namely the javafx.scene.shape.Shape class and the javafx.scene.Node class. See the JavaFX API documentation for details.

Introduction

FXD (an acronym for Java FX Data) is a textual format for storing graphics following JavaFX Script object literal syntax. It is easy to process and edit in a variety of tools and enables storing metadata used by tools.

FXD files are typically stored in compressed FXZ archives. An FXZ archive is a normal compressed (zip) archive, but it has an FXZ extension. It is therefore possible to open and modify FXZ archives using any tool that supports normal zip files. As Figure 1 shows, FXZ archive files can contain additional embedded assets: vector graphics, bitmap images, animations, TrueType fonts, video files, audio files, UI controls, and the FXD document. A single FXZ resource thus can define a quite complex application UI. FXZ files are loaded into JavaFX applications, and the assets can be manipulated by application logic in the JavaFX Script programming language.

 

Figure 1: FXD archive context diagram

Basics of FXD Format

The grammar for the FXD textual format is similar to JSON syntax, modified to be more like the JavaFX Script programming language. The elements and properties allowed in FXD documents are defined by an FXD schema.

FXD documents contain the following components:

  • Version information
  • Content elements, which have associated properties
  • A single root element, called FXD, under which all other elements must be nested
  • Comments

The following example shows all three components, and each component is described in the following sections.

          /** Created on Tue Jul 28 16:30:28 CEST 2009   */ //@version 1.3     FXD {     content: [         Rectangle {                  x: 10             y: 10             width: 50             height: 50             fill: Color.RED                       }    ] }
      

Version Information

Version information is optional, but when provided must precede any element declaration. The version information starts with prefix //@version, as shown in the previous example.

Elements and Properties

Content in FXD documents is defined in elements, which are mapped to JavaFX objects in JavaFX Script applications. Elements can contain properties, which are similar to variables in JavaFX Script. Properties are wrapped in curly braces following the element name.

FXD Root Element

FXD documents must have a single root element, and this root element must always be FXD. The FXD element can only occur in the root position. It can contain any of the following properties.

  • content - All content elements that describe the content to be included in the scenegraph are nested under the content property. The content property contains one or more elements as values, wrapped in square brackets. In the previous example, the content property contains only one nested element.
  • libraries - All elements that are stored as symbols for potential inclusion in the scenegraph are nested under the libraries property. For more information, see Libraries.
  • actions - Elements that define animation are nested under the actions property.Currently, only the Timeline element may be included in this property.

Comments

Both single-line and multiline comments are supported. Commenting notation is the same as for the Java programming language. Precede single-line comments with two forward slashes //. Wrap multiline comments with /* at the beginning and */ at the end, as shown in the following example:

          //Single-line comment /* Multi-line comment */
      

Identifiers

All FXD elements can optionally have a property called id. All FXD elements that contain the id property can be referenced in a JavaFX Script application using the id value. An FXD element is directly mapped to a JavaFX Script object instance when both contain the same id property value. If the id property is missing in the JavaFX Script object instance, then the mapping between the FXD element and its id value is stored in an FXDContent instance in the JavaFX Script code, so it can be later used for node lookup.

FXD format does not force the id property value to be unique. This means that there can be several elements with the same id value in one FXD document. The id property requires a string value, and any character, including whitespaces, can be used in the string. However, since string values must be delimited with double quotes in FXD format, it is a good idea to avoid double-quote characters in the value. Although not required, a good heuristic is to conform to the lexical structure of Java identifiers, as show on in the following example.

          FXD {     content: [         Rectangle {                 id: "            myRect1"              x: 10             y: 10             width: 50             height: 50             fill: LinearGradient {                  id: "            myGrad1"                 startX: 0                 startY:0                  endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                    }    ] }         
      

Metadata

Metadata refers to arbitrary properties, other than those properties defined for each element in this specification, which can be attached to any FXD element. Metadata names are delimited with double quotes to differentiate them from properties that are used to construct JavaFX objects. Metadata values are defined in the same way as values for regular properties.

Metadata are application-specific, in that their names and types are defined not by FXD specification but rather by the application that uses the FXD content.. With one exception, metadata are transparent to the FXDLoader class in the JavaFX API, which loads FXZ and FXD content at runtime. The FXDLoader class merely parses metadata and makes it available for application logic.

The one metadata property that is understood by FXDLoader is the uid property, which represents a unique element ID. Unlike id property identifiers, the uid property must be unique within an FXD document's scope. It is completely independent from the id property and may be used to identify elements in situations in which the id property cannot be used. One such situation is when the id property contains user-defined values that are not unique but cannot be changed since they must be preserved, and thus cannot be used for element identification.

The following FXD snippet shows an example of the "uid" metadata property and two other examples of user-defined metadata: "can-explode" and "explosion-sound".

          Rectangle {     id: "rect"                  "uid": "rectangle1"     x: 10     y: 11     width: 40     height: 40     fill: Color.RED                  "can-explode": true                  "explosion-sound": "bang.mp3" }         
      

References

References enable an element or property to be defined just once and reused by pointing to it. References can be used anywhere that an element declaration is allowed in FXD content. References are specific to FXD format and do not have a direct equivalent in the JavaFX Script programming language.

Forward references and references to elements or properties in other FXD documents are allowed.

Reference Notation

FXD references have the following structure.

$ref: [archive-url]/ [document-name]# [prefix]:<element-id>. [property-name]

where:
[archive-url] specifies the location of the FXD document. This component can be omitted if the reference points to an element within the scope of the same FXD document.
[document-name] is name of the FXD document file. This component can be omitted if the reference points to an element within the scope of the same FXD document.
[prefix] specifies how the element identifier in <element-id> should be interpreted. This element is optional, and when it does not appear, the trailing colon (:) must be removed as well. When the prefix is not specified, the <element-id> specifies the ID value. Currently allowed prefixes are uid and select. See the section Other Ways to Reference Elements for details.
<element-id> specifies an element identification. This component is required.
[property-name] specifies an optional element property name and is used only when you want a reference to a property of an element, rather than the element itself.

When the reference omits the [archive-url] and [document-name] components, you can omit the $ref prefix.

Reference Examples

The following example shows a reference containing only the obligatory <element-id> component. The fill property in the second rectangle references the ID for the LinearGradient element in the first rectangle. The result is that both rectangles share the same linear gradient.

          FXD {     content: [         Rectangle {                 id: "myRect1"              x: 10             y: 10             width: 50             height: 50             fill: LinearGradient {                               id: "myGrad1"                  startX: 0                 startY:0                  endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                    },         Rectangle {             x: 10             y: 10             width: 50             height: 50                          fill: #myGrad1  //references LinearGradient element through its ID value         }    ] }         
      

Because the referenced ID value conforms to the lexical structure of Java identifiers, the reference can use a simplified notation without quotation marks. If the referenced ID value contains a string that does not conform to the lexical structure of Java identifiers, the reference must be wrapped in double quotes, as shown in the following example.

          FXD {     content: [         Rectangle {                 id: "myRect1"              x: 10             y: 10             width: 50             height: 50             fill: LinearGradient {                               id: "my weird id" //this string value contains a space                 startX: 0                 startY:0                  endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                    },         Rectangle {             x: 10             y: 10             width: 50             height: 50                          fill: #"my weird id" //reference is in double quotes          }    ] }         
      

The following example demonstrates a reference to an element property. The reference points to the height property of the Rectangle element, which has the id value myRect1. As a result, the value for the height property is shared by the two rectangles.

          FXD {     content: [         Rectangle {                              id: "myRect1"              x: 10             y: 10             width: 50                          height: 50             fill: LinearGradient {                  id: "myGrad1"                 startX: 0                 startY:0                  endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                    },         Rectangle {             x: 10             y: 10             width: 50             height:              #myRect1.height  	               //references the height property of object with id "MyRect1"             fill: #myGrad1         }    ] }         
      

The following example uses the [archive-url] option to reference an element in another FXD file on the web. The fill variable gets its value from an element with id value myGrad1 in the FXD File named MyFXDFile.fxd, located at http:www.example.com.

          FXD {     content: [         Rectangle {             x: 10             y: 10             width: 50             height: 50                           fill: $ref:http:www.example.com/MyFXDFile.fxd#myGrad1          }    ] }         
      

For more reference examples, see the Reference Summary.

Reference Handling at Runtime

References are resolved at runtime by the FXDLoader class in the JavaFX API. No support is required from the JavaFX runtime or scenegraph. Referenced object instances are handled in one of two possible ways:

  • Share - The referenced element is reused, rather than a new instance being created. Sharing occurs for elements that can be reused in the scenegraph. For example, Gradient or Color object instances can be used as variable values in many nodes throughout the application.
  • Copy - The referenced object is duplicated, and its duplicate is used. Copying occurs for objects that cannot be reused in the scenegraph, or for objects that never appear in the scenegraph.

The FXDLoader class decides if a referenced object can be shared or if it needs to be copied. In most cases, the preference for Share or Copy is unambiguous. In ambiguous cases, the use of Share or Copy is decided based on the context of the property that uses the reference. For example, Node.fill uses Share, whereas Node.clip uses Copy. This is because the variable instances that express gradients, effects, and colors can be used many times in a scenegraph, whereas the clip variable is of type Node, and node instances can only be used once in a scenegraph.

In some situations, for example with referenced Effect objects, it is not always clear from the context what type of reference to use. In the case of such ambiguity, the FXDLoader class chooses the Share reference.

You can force the Copy reference by using the double hash ## instead of the usual single hash in a reference. In the following example, a Copy reference to the Reflection element is forced by the double hash in the <element-id> reference.

$ref: ##rect.effect

          FXD {     content: [         Rectangle {                 id: "myRect1"              x: 10             y: 10             width: 50             height: 50             fill: Color.RED             effect: Reflection {                               id: "Reflect1"                 fraction: 0.7              }         Rectangle {             x: 10             y: 10             width: 50             height: #myRect1.height             fill: Color.BLUE             effect:              ##Reflect1  //Two cross-hatches force Copy         }    ] }         
      

Other Ways to Reference Elements

You can use the element metadata uid or more complex queries, similar to the XPath query notation used for XML content. In these cases, the <element-id> part of the reference is preceded with the [prefix] option, which changes the meaning of the rest of reference. The following prefixes, or "protocols," are supported:

  • uid: - The text following this prefix is interpreted as a uid metadata property value, rather than an id value. For example: #uid:rectangle1 denotes the element with uid value equal to "rectangle1".
  • select: - The text following this prefix is interpreted as a query. The query syntax uses element identifiers and property names to determine what will be selected. The element identifiers are separated with forward slash characters (/), and a period (.) is used to denote a property. Elements without any id property defined are skipped completely during query resolution. For example, the reference #select:/body/hand/finger.x denotes property x of the element, with id:finger, which is a child of the element with id:hand, whose parent is the element with id:body.
See the Reference Summary section for examples.

Reference Summary

The following table provides examples of FXD references or queries.

Reference Description
#rect1 Element with id value rect1 in local FXD document.
$ref:#rect1 Same as above. The $ref prefix can be omitted when the first component is the <element-id> .
$ref:content-1.fxd#rect1 The element with id value rect1 in the FXD document content-1.fxd in the same directory or package as the current document.
$ref:../content-1.fxd#root The element with id value root in the FXD document content-1.fxd in the parent directory or package as the current document.
$ref:http:/www.example.com/cat.fxd#paw The element with id value paw in a remote FXD document on the web.
#"my rectangle" Element with id value my rectangle in the local FXD document. Double quotes are required because the value has a white space.
#uid:gradient Element with metadata uid value gradient in local FXD document.
#uid:"my gradient" Element with metadata uid value gradient in local FXD document.
#rect1.x Property x of an element with id value rect1
#uid:"my gradient".startX Property startX of an element with metadata uid value my gradient. Double quotes are required because the value has a white space.
#select:/body/hand/finger Element in local document with id value finger, which is a child of element with id value hand, whose parent is an element with id value body.
#select:/body/hand/finger.translateX Property translateX of an element in a local document with id value finger, which is a child of an element with id value hand, whose parent is some element with id value body.

 

Extensions

Extensions enable you to reuse some of the properties in referenced elements but override others, or add more properties. For example, you can use an extension to reuse the color and spread for a linear gradient but specify a different location where the gradient applies.

To add an extension, reference an element in the normal fashion, then define any new properties and properties with override values, as shown in the following example.

          FXD {     content: [         Rectangle {                 id: "myRect1"              x: 10             y: 10             width: 50             height: 50             fill: LinearGradient {                               id: "myGrad1" //Assign an id to the linear gradient declaration                 startX: 0                 startY:0                  endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                    },         Rectangle {             id: "newRect"             x: 10             y: 10             width: 50             height: 50                          fill: #myGrad1 {   //Reference the linear gradient                 startX: 40   //Override the startX property                 startY: 40   //Override the startY property              }         }    ] }         
      

You can extend the definition of any element that can be referenced. The extended definition overrides or adds any properties that are allowed for the extended element type, as determined by the corresponding class in JavaFX Script.

Extending an element is equivalent to fully specifying an element's properties in another place in the document. For example, the description in the previous example produces the same result as the following description, in which the properties of the second linear gradient are fully specified.

          FXD {     content: [         Rectangle {                 id: "myRect1"              x: 10             y: 10             width: 50             height: 50             fill: LinearGradient {                  id: "myGrad1"                  startX: 0                 startY:0                  endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                    },         Rectangle {             id: "newRect"             x: 10             y: 10             width: 50             height: 50                          fill: LinearGradient {  //Define all the properties of the linear gradient                 startX: 40                 startY: 40                 id: "myGrad1"                 endX: 100                  endY: 100                  stops: [                      Stop {                         offset: 0.0                          color: Color.WHITE                     },                     Stop {                         offset: 1.0                          color: Color.BLACK                     }                ]}                        }         }    ] }         
      

Note: Nested extension is not supported. For example, the second rectangle and its gradient cannot both be extended.

Libraries

The elements defined within the content property of the FXD element are inserted into a scenegraph when the content is loaded. The elements, converted to nodes, are visible on screen unless explicitly hidden. However, on occasion you might want to store elements in a way that they can be inserted into the scenegraph by using a reference. The elements are treated as symbols for reuse and stored in a library that is separate from the scenegraph. Storing elements as symbols in a library enables them to be referenced from many places in a document. For example, you might want to store separately and reference symbols in a topographical map.

The property libraries of the FXD root serves as the container for symbol libraries. The elements defined there must be referenced from a node in the scene to appear in the scene.

In the following example, a rectangle is defined as a library symbol and referenced once in the scene. The translateY property of the Group element moves the y-coordinate position of the first rectangle 200 pixels lower.

          FXD {                  libraries: [         Rectangle {                          id: "rect"             x: 10             y: 15             width: 60             height: 50             stroke: Color.RED             fill: Color.BLUE         }     ]     content: [         Group {                           translateY: 200              content: [                               #rect             ]         },      ] }         
      

In the previous example, the Group element was used to change the y coordinate. You can also use an extension to change the y coordinate, as follows.

          FXD {     libraries: [         Rectangle {  //the first rectangle             id: "rect"             x: 10             y: 15             width: 60             height: 50             stroke: Color.RED             fill: Color.BLUE         }     ]     content: [                                                          #rect {   //the second rectangle              y: 200                      },     ] }          
      

Animations

FXD format can contain JavaFX animations, which are defined in the actions property of the root FXD element. The following example shows a simple animation of a red rectangle moving along the x-axis.

          FXD {     actions: [         Timeline {             id: "move"             repeatCount: 1             autoReverse: false             keyFrames: [                 KeyFrame {                     time: 3000                     values: [ KeyValue { target: #rect.x value: 40} ]                 },             ]         }     ]      content: [         Rectangle {             id: "rect"             x: 10             y: 11             width: 40             height: 40             fill: Color.RED         }     ] }
      

Another example shows how same thing can be achieved using a simple transition.

          FXD {     actions: [         TranslateTransition {             id: "move"             duration: 3000             node: #rect             fromX: 10             toX: 40             autoReverse: false             repeatCount: 1         }     ]           content: [         Rectangle {             id: "rect"             x: 10             y: 11             width: 40             height: 40             fill: Color.RED                         } 	  ] }
      

Please note that the animations are not started automatically. They must be explicitly triggered from application code, for example:

                      	var action = fxdContent.getObject("move") as Timeline; 	action.play();         
      

 

 
 
 
false ,,,,,,,,,,,,,,,