FXD Specification 1.3
FXD Format
This specification contains the following sections:
- How to Use This Specification
- Introduction
- Basics of FXD Format
- Identifiers
- Metadata
- References
- Extensions
- Libraries
- Animations
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 JavaFX 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 thecontentproperty. Thecontentproperty contains one or more elements as values, wrapped in square brackets. In the previous example, thecontentproperty contains only one nested element.libraries- All elements that are stored as symbols for potential inclusion in the scenegraph are nested under thelibrariesproperty. For more information, see Libraries.actions- Elements that define animation are nested under the actions property.Currently, only theTimelineelement may be included in this property.
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,
GradientorColorobject 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
uidmetadata property value, rather than anidvalue. For example:#uid:rectangle1denotes the element withuidvalue 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
idproperty defined are skipped completely during query resolution. For example, the reference#select:/body/hand/finger.xdenotes propertyxof the element, withid:finger, which is a child of the element withid:hand, whose parent is the element withid:body.
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();