Sei sulla pagina 1di 15

06/08/13

Introduction to FXML | JavaFX 2.2

R e le ase : JavaFX 2.2

Introduction to FXML
Last updated: 6/21/2012

Contents
Overview Elements Class Instance Elements Instance Declarations <fx:include> <fx:constant> <fx:reference> <fx:copy> <fx:root> Property Elements Property Setters Read-Only List Properties Read-Only Map Properties Default Properties Static Properties Define Blocks Attributes Instance Properties Location Resolution Resource Resolution Variable Resolution Escape Sequences Expression Binding Static Properties Event Handlers Script Event Handlers Controller Method Event Handlers Scripting Controllers @FXML Nested Controllers FXMLLoader Custom Components

Overview
FXML is a scriptable, XML-based markup language for constructing Java object graphs. It provides a convenient alternative to constructing such graphs in procedural code, and is ideally suited to defining the user interface of a JavaFX application, since the hierarchical structure of an XML document closely parallels the structure of the JavaFX scene graph. This document introduces the FXML markup language and explains how it can be used to simplify development of JavaFX applications.

docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html

1/15

06/08/13

Introduction to FXML | JavaFX 2.2

Elements
In FXML, an XML element represents one of the following: A class instance A property of a class instance A "static" property A "define" block A block of script code Class instances, instance properties, static properties, and define blocks are discussed in this section below. Scripting is discussed in a later section.

Class Instance Elements


Class instances can be constructed in FXML in several ways. The most common is via instance declaration elements, which simply create a new instance of a class by name. Other ways of creating class instances include referencing existing values, copying existing values, and including external FXML files. Each is discussed in more detail below.

Instance Declarations
If an element's tag name begins with an uppercase letter (and it is not a "static" property setter, described later), it is considered an instance declaration. When the FXML loader (also introduced later) encounters such an element, it creates an instance of that class. As in Java, class names can be fully-qualified (including the package name), or they can be imported using the "import" processing instruction (PI). For example, the following PI imports the j a v a f x . s c e n e . c o n t r o l . L a b e lclass into the current FXML documents namespace:
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . L a b e l ? >

This PI imports all classes from the javafx.scene.control package into the current namespace:
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? >

Any class that adheres to JavaBean constructor and property naming conventions can be readily instantiated and configured using FXML. The following is a simple but complete example that creates an instance of j a v a f x . s c e n e . c o n t r o l . L a b e land sets its "text" property to "Hello, World!":
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . L a b e l ? > < L a b e lt e x t = " H e l l o ,W o r l d ! " / >

Note that the L a b e l s "text" property in this example is set using an XML attribute. Properties can also be set using nested property elements. Property elements are discussed in more detail later in this section. Property attributes are discussed in a later section. Classes that don't conform to Bean conventions can also be constructed in FXML, using an object called a "builder". Builders are discussed in more detail later. Maps Internally, the FXML loader uses an instance of c o m . s u n . j a v a f x . f x m l . B e a n A d a p t e rto wrap an instantiated object and invoke its setter methods. This (currently) private class implements the j a v a . u t i l . M a pinterface and allows a caller to get and set Bean property values as key/value pairs. If an element represents a type that already implements M a p(such as j a v a . u t i l . H a s h M a p ), it is not wrapped and its g e t ( )and p u t ( )methods are invoked directly. For example, the following FXML creates an instance of H a s h M a pand sets its "foo" and "bar" values to "123" and "456", respectively:
< H a s h M a pf o o = " 1 2 3 "b a r = " 4 5 6 " / >

fx:value The f x : v a l u eattribute can be used to initialize an instance of a type that does not have a default constructor but provides a static v a l u e O f ( S t r i n g )method. For example, j a v a . l a n g . S t r i n gas well as each of the primitive wrapper types define a v a l u e O f ( )method and can be constructed in FXML as follows:
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 2/15

06/08/13

Introduction to FXML | JavaFX 2.2

< S t r i n gf x : v a l u e = " H e l l o ,W o r l d ! " / > < D o u b l ef x : v a l u e = " 1 . 0 " / > < B o o l e a nf x : v a l u e = " f a l s e " / >

Custom classes that define a static v a l u e O f ( S t r i n g )method can also be constructed this way. fx:factory The f x : f a c t o r yattribute is another means of creating objects whose classes do not have a default constructor. The value of the attribute is the name of a static, no-arg factory method for producing class instances. For example, the following markup creates an instance of an observable array list, populated with three string values:
< F X C o l l e c t i o n sf x : f a c t o r y = " o b s e r v a b l e A r r a y L i s t " > < S t r i n gf x : v a l u e = " A " / > < S t r i n gf x : v a l u e = " B " / > < S t r i n gf x : v a l u e = " C " / > < / F X C o l l e c t i o n s >

Builders A third means of creating instances of classes that do not conform to Bean conventions (such as those representing immutable values) is a "builder". The builder design pattern delegates object construction to a mutable helper class (called a "builder") that is responsible for manufacturing instances of the immutable type. Builder support in FXML is provided by two interfaces. The j a v a f x . u t i l . B u i l d e rinterface defines a single method named b u i l d ( )which is responsible for constructing the actual object:
p u b l i ci n t e r f a c eB u i l d e r < T >{ p u b l i cTb u i l d ( ) ; }

Aj a v a f x . u t i l . B u i l d e r F a c t o r yis responsible for producing builders that are capable of instantiating a given type:
p u b l i ci n t e r f a c eB u i l d e r F a c t o r y{ p u b l i cB u i l d e r < ? >g e t B u i l d e r ( C l a s s < ? >t y p e ) ; }

A default builder factory, J a v a F X B u i l d e r F a c t o r y , is provided in the j a v a f x . f x m lpackage. This factory is capable of creating and configuring most immutable JavaFX types. For example, the following markup uses the default builder to create an instance of the immutable j a v a f x . s c e n e . p a i n t . C o l o rclass:
< C o l o rr e d = " 1 . 0 "g r e e n = " 0 . 0 "b l u e = " 0 . 0 " / >

Note that, unlike Bean types, which are constructed when the element's start tag is processed, objects constructed by a builder are not instantiated until the element's closing tag is reached. This is because all of the required arguments may not be available until the element has been fully processed. For example, the Color object in the preceding example could also be written as:
< C o l o r > < r e d > 1 . 0 < / r e d > < g r e e n > 0 . 0 < / g r e e n > < b l u e > 0 . 0 < / b l u e > < / C o l o r >

The C o l o rinstance cannot be fully constructed until all three of the color components are known. When processing markup for an object that will be constructed by a builder, the B u i l d e rinstances are treated like value objects - if a B u i l d e rimplements the M a pinterface, the p u t ( )method is used to set the builder's attribute values. Otherwise, the builder is wrapped in a B e a n A d a p t e rand its properties are assumed to be exposed via standard Bean setters.

<fx:include>
The < f x : i n c l u d e >tag creates an object from FXML markup defined in another file. It is used as follows:
< f x : i n c l u d es o u r c e = " f i l e n a m e " / >

where filename is the name of the FXML file to include. Values that begin with a leading slash character are treated as relative to the classpath. Values with no leading slash are considered relative to the path of the current document.
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 3/15

06/08/13

Introduction to FXML | JavaFX 2.2

For example, given the following markup:


< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < ? i m p o r tj a v a f x . s c e n e . l a y o u t . * ? > < V B o xx m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < c h i l d r e n > < f x : i n c l u d es o u r c e = " m y _ b u t t o n . f x m l " / > < / c h i l d r e n > < / V B o x >

If m y _ b u t t o n . f x m lcontains the following:


< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < B u t t o nt e x t = " M yB u t t o n " / >

the resulting scene graph would contain a V B o xas a root object with a single B u t t o nas a child node. Note the use of the "fx" namespace prefix. This is a reserved prefix that defines a number of elements and attributes that are used for internal processing of an FXML source file. It is generally declared on the root element of a FXML document. Other features provided by the "fx" namespace are described in the following sections.
< f x : i n c l u d e >also supports attributes for specifying the name of the resource bundle that should be used to localize

the included content, as well as the character set used to encode the source file. Resource resolution is discussed in a later section.

<fx:constant>
The < f x : c o n s t a n t >element creates a reference to a class constant. For example, the following markup sets the value of the "minWidth" property of aB u t t o ninstance to the value of the N E G A T I V E _ I N F I N I T Yconstant defined by the j a v a . l a n g . D o u b l eclass:
< B u t t o n > < m i n H e i g h t > < D o u b l ef x : c o n s t a n t = " N E G A T I V E _ I N F I N I T Y " / > < / m i n H e i g h t > < / B u t t o n >

<fx:reference>
The < f x : r e f e r e n c e >element creates a new reference to an existing element. Wherever this tag appears, it will effectively be replaced by the value of the named element. It is used in conjunction with either the f x : i dattribute or with a script variables, both of which are discussed in more detail in later sections. The "source" attribute of the < f x : r e f e r e n c e >element specifies the name of the object to which the new element will refer. For example, the following markup assigns a previously-defined I m a g einstance named "myImage" to the "image" property of an I m a g e V i e wcontrol:
< I m a g e V i e w > < i m a g e > < f x : r e f e r e n c es o u r c e = " m y I m a g e " / > < / i m a g e > < / I m a g e V i e w >

Note that, since it is also possible to dereference a variable using the attribute variable resolution operator (discussed later in the Attributes section), f x : r e f e r e n c eis generally only used when a reference value must be specified as an element, such as when adding the reference to a collection:
< A r r a y L i s t > < f x : r e f e r e n c es o u r c e = " e l e m e n t 1 " / > < f x : r e f e r e n c es o u r c e = " e l e m e n t 2 " / > < f x : r e f e r e n c es o u r c e = " e l e m e n t 3 " / > < / A r r a y L i s t >

For most other cases, using an attribute is simpler and more concise.

<fx:copy>
The < f x : c o p y >element creates a copy of an existing element. Like < f x : r e f e r e n c e > , it is used with the fx:id attribute or a script variable. The element's "source" attribute specifies the name of the object that will be copied. The source type must define a copy constructor that will be used to construct the copy from the source value.
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 4/15

06/08/13

Introduction to FXML | JavaFX 2.2

At the moment, no JavaFX platform classes provide such a copy constructor, so this element is provided primarily for use by application developers. This may change in a future release.

<fx:root>
The < f x : r o o t >element creates a reference to a previously defined root element. It is only valid as the root node of an FXML document. < f x : r o o t >is used primarily when creating custom controls that are backed by FXML markup. This is discussed in more detail in the FXMLLoader section.

Property Elements
Elements whose tag names begin with a lowercase letter represent object properties. A property element may represent one of the following: A property setter A read-only list property A read-only map property

Property Setters
If an element represents a property setter, the contents of the element (which must be either a text node or a nested class instance element) are passed as the value to the setter for the property. For example, the following FXML creates an instance of the L a b e lclass and sets the value of the label's "text" property to "Hello, World!":
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . L a b e l ? > < L a b e l > < t e x t > H e l l o ,W o r l d ! < / t e x t > < / L a b e l >

This produces the same result as the earlier example which used an attribute to set the "text" property:
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . L a b e l ? > < L a b e lt e x t = " H e l l o ,W o r l d ! " / >

Property elements are generally used when the property value is a complex type that can't be represented using a simple string-based attribute value, or when the character length of the value is so long that specifying it as an attribute would have a negative impact on readability. Type Coercion FXML uses "type coercion" to convert property values to the appropriate type as needed. Type coercion is required because the only data types supported by XML are elements, text, and attributes (whose values are also text). However, Java supports a number of different data types including built-in primitive value types as well as extensible reference types. The FXML loader uses the c o e r c e ( )method of B e a n A d a p t e rto perform any required type conversions. This method is capable of performing basic primitive type conversions such as S t r i n gto b o o l e a nor i n tto d o u b l e , and will also convert S t r i n gto C l a s sor S t r i n gto E n u m . Additional conversions can be implemented by defining a static v a l u e O f ( )method on the target type.

Read-Only List Properties


A read-only list property is a Bean property whose getter returns an instance of j a v a . u t i l . L i s tand has no corresponding setter method. The contents of a read-only list element are automatically added to the list as they are processed. For example, the "children" property of j a v a f x . s c e n e . G r o u pis a read-only list property representing the group's child nodes:
< ? i m p o r tj a v a f x . s c e n e . * ? > < ? i m p o r tj a v a f x . s c e n e . s h a p e . * ? > < G r o u px m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < c h i l d r e n > < R e c t a n g l ef x : i d = " r e c t a n g l e "x = " 1 0 "y = " 1 0 "w i d t h = " 3 2 0 "h e i g h t = " 2 4 0 " f i l l = " # f f 0 0 0 0 " / >
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 5/15

06/08/13

Introduction to FXML | JavaFX 2.2

. . . < / c h i l d r e n > < / G r o u p >

As each sub-element of the < c h i l d r e n >element is read, it is added to the list returned by G r o u p # g e t C h i l d r e n ( ) .

Read-Only Map Properties


A read-only map property is a bean property whose getter returns an instance of j a v a . u t i l . M a pand has no corresponding setter method. The attributes of a read-only map element are applied to the map when the closing tag is processed. The "properties" property of j a v a f x . s c e n e . N o d eis an example of a read-only map property. The following markup sets the "foo" and "bar" properties of a L a b e linstance to "123" and "456", respectively:
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < B u t t o n > < p r o p e r t i e sf o o = " 1 2 3 "b a r = " 4 5 6 " / > < / B u t t o n >

Note that a read-only property whose type is neither a L i s tnor a M a pwill be treated as if it were a read-only map. The return value of the getter method will be wrapped in a B e a n A d a p t e rand can be used in the same way as any other read-only map.

Default Properties
A class may define a "default property" using the @ D e f a u l t P r o p e r t yannotation defined in the j a v a f x . b e a n s package. If present, the sub-element representing the default property can be omitted from the markup. For example, since j a v a f x . s c e n e . l a y o u t . P a n e(the superclass of j a v a f x . s c e n e . l a y o u t . V B o x ) defines a default property of "children", a < c h i l d r e n >element is not required; the loader will automatically add the sub-elements of the V B o xto the container's "children" collection:
< ? i m p o r tj a v a f x . s c e n e . * ? > < ? i m p o r tj a v a f x . s c e n e . s h a p e . * ? > < V B o xx m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < B u t t o nt e x t = " C l i c kM e ! " / > . . . < / V B o x >

Note that default properties are not limited to collections. If an element's default property refers to a scalar value, any sub-element of that element will be set as the value of the property. For example, since j a v a f x . s c e n e . c o n t r o l . S c r o l l P a n edefines a default property of "content", a scroll pane containing a T e x t A r e aas its content can be specified as follows:
< S c r o l l P a n e > < T e x t A r e at e x t = " O n c eu p o nat i m e . . . " / > < / S c r o l l P a n e >

Taking advantage of default properties can significantly reduce the verbosity of FXML markup.

Static Properties
An element may also represent a "static" property (sometimes called an "attached property"). Static properties are properties that only make sense in a particular context. They are not intrinsic to the class to which they are applied, but are defined by another class (often, the parent container of a control). Static properties are prefixed with the name of class that defines them. For example, The following FXML invokes the static setter for G r i d P a n e 's "rowIndex" and "columnIndex" properties:
< G r i d P a n e > < c h i l d r e n > < L a b e lt e x t = " M yL a b e l " > < G r i d P a n e . r o w I n d e x > 0 < / G r i d P a n e . r o w I n d e x > < G r i d P a n e . c o l u m n I n d e x > 0 < / G r i d P a n e . c o l u m n I n d e x > < / L a b e l > < / c h i l d r e n >
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 6/15

06/08/13

Introduction to FXML | JavaFX 2.2

< / T a b P a n e >

This translates roughly to the following in Java:


G r i d P a n eg r i d P a n e=n e wG r i d P a n e ( ) ; L a b e ll a b e l=n e wL a b e l ( ) ; l a b e l . s e t T e x t ( " M yL a b e l " ) ; G r i d P a n e . s e t R o w I n d e x ( l a b e l ,0 ) ; G r i d P a n e . s e t C o l u m n I n d e x ( l a b e l ,0 ) ; g r i d P a n e . g e t C h i l d r e n ( ) . a d d ( l a b e l ) ;

The calls to G r i d P a n e # s e t R o w I n d e x ( )and G r i d P a n e # s e t C o l u m n I n d e x ( )"attach" the index data to the L a b e l instance. G r i d P a n ethen uses these during layout to arrange its children appropriately. Other containers, including A n c h o r P a n e ,B o r d e r P a n e , and S t a c k P a n e , define similar properties. As with instance properties, static property elements are generally used when the property value cannot be efficiently represented by an attribute value. Otherwise, static property attributes (discussed in a later section) will generally produce more concise and readable markup.

Define Blocks
The < f x : d e f i n e >element is used to create objects that exist outside of the object hierarchy but may need to be referred to elsewhere. For example, when working with radio buttons, it is common to define a T o g g l e G r o u pthat will manage the buttons' selection state. This group is not part of the scene graph itself, so should not be added to the buttons' parent. A define block can be used to create the button group without interfering with the overall structure of the document:
< V B o x > < f x : d e f i n e > < T o g g l e G r o u pf x : i d = " m y T o g g l e G r o u p " / > < / f x : d e f i n e > < c h i l d r e n > < R a d i o B u t t o nt e x t = " A "t o g g l e G r o u p = " $ m y T o g g l e G r o u p " / > < R a d i o B u t t o nt e x t = " B "t o g g l e G r o u p = " $ m y T o g g l e G r o u p " / > < R a d i o B u t t o nt e x t = " C "t o g g l e G r o u p = " $ m y T o g g l e G r o u p " / > < / c h i l d r e n > < / V B o x >

Elements in define blocks are usually assigned an ID that can be used to refer to the element's value later. IDs are discussed in more detail in later sections.

Attributes
An attribute in FXML may represent one of the following: A property of a class instance A "static" property An event handler Each are discussed in more detail in the following sections.

Instance Properties
Like property elements, attributes can also be used to configure the properties of a class instance. For example, the following markup creates a B u t t o nwhose text reads "Click Me!":
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < B u t t o nt e x t = " C l i c kM e ! " / >

As with property elements, property attributes support type coercion. When the following markup is processed, the "x", "y", "width", and "height" values will be converted to doubles, and the "fill" value will be converted to a C o l o r :
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 7/15

06/08/13

Introduction to FXML | JavaFX 2.2

< R e c t a n g l ef x : i d = " r e c t a n g l e "x = " 1 0 "y = " 1 0 "w i d t h = " 3 2 0 "h e i g h t = " 2 4 0 " f i l l = " # f f 0 0 0 0 " / >

Unlike property elements, which are applied as they are processed, property attributes are not applied until the closing tag of their respective element is reached. This is done primarily to facilitate the case where an attribute value depends on some information that won't be available until after the element's content has been completely processed (for example, the selected index of a T a b P a n econtrol, which can't be set until all of the tabs have been added). Another key difference between property attributes and property elements in FXML is that attributes support a number of "resolution operators" that extend their functionality. The following operators are supported and are discussed in more detail below: Location resolution Resource resolution Variable resolution

Location Resolution
As strings, XML attributes cannot natively represent typed location information such as a URL. However, it is often necessary to specify such locations in markup; for example, the source of an image resource. The location resolution operator (represented by an "@" prefix to the attribute value) is used to specify that an attribute value should be treated as a location relative to the current file rather than a simple string. For example, the following markup creates an ImageView and populates it with image data from m y _ i m a g e . p n g , which is assumed to be located at a path relative to the current FXML file:
< I m a g e V i e w > < i m a g e > < I m a g eu r l = " @ m y _ i m a g e . p n g " / > < / i m a g e > < / I m a g e V i e w >

Since I m a g eis an immutable object, a builder is required to construct it. Alternatively, if I m a g ewere to define a v a l u e O f ( U R L )factory method, the image view could be populated as follows:
< I m a g e V i e wi m a g e = " @ m y _ i m a g e . p n g " / >

The value of the "image" attribute would be converted to a URL by the FXML loader, then coerced to an I m a g eusing the v a l u e O f ( )method.

Resource Resolution
In FXML, resource substitution can be performed at load time for localization purposes. When provided with an instance of j a v a . u t i l . R e s o u r c e B u n d l e , the FXML loader will replace instances of resource names with their localespecific values. Resource names are identified by a "%" prefix, as shown below:
< L a b e lt e x t = " % m y T e x t " / >

If the loader is given a resource bundle defined as follows:


m y T e x t=T h i si st h et e x t !

the output of the FXML loader would be a L a b e linstance containing the text "This is the text!".

Variable Resolution
An FXML document defines a variable namespace in which named elements and script variables may be uniquely identified. The variable resolution operator allows a caller to replace an attribute value with an instance of a named object before the corresponding setter method is invoked. Variable references are identified by a "$" prefix, as shown below:
< f x : d e f i n e > < T o g g l e G r o u pf x : i d = " m y T o g g l e G r o u p " / > < / f x : d e f i n e > . . . < R a d i o B u t t o nt e x t = " A "t o g g l e G r o u p = " $ m y T o g g l e G r o u p " / > < R a d i o B u t t o nt e x t = " B "t o g g l e G r o u p = " $ m y T o g g l e G r o u p " / > < R a d i o B u t t o nt e x t = " C "t o g g l e G r o u p = " $ m y T o g g l e G r o u p " / >
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 8/15

06/08/13

Introduction to FXML | JavaFX 2.2

Assigning an f x : i dvalue to an element creates a variable in the document's namespace that can later be referred to by variable dereference attributes, such as the "toggleGroup" attribute shown above, or in script code, discussed in a later section. Additionally, if the object's type defines an "id" property, this value will also be passed to the objects s e t I d ( )method.

Escape Sequences
If the value of an attribute begins with one of the resource resolution prefixes, the character can be escaped by prepending it with a leading backslash ("\") character. For example, the following markup creates a L a b e linstance whose text reads "$10.00":
< L a b e lt e x t = " \ $ 1 0 . 0 0 " / >

Expression Binding
Attribute variables as shown above are resolved once at load time. Later updates to the variables value are not automatically reflected in any properties to which the value was assigned. In many cases, this is sufficient; however, it is often convenient to "bind" a property value to a variable or expression such that changes to the variable are automatically propagated to the target property. Expression bindings can be used for this purpose. An expression binding also begins with the variable resolution operator, but is followed by a set of curly braces which wrap the expression value. For example, the following markup binds the value of a text input's "text" property to the "text" property of a L a b e linstance:
< T e x t F i e l df x : i d = " t e x t F i e l d " / > < L a b e lt e x t = " $ { t e x t F i e l d . t e x t } " / >

As the user types in the text input, the label's text content will be automatically updated. Only simple expressions that resolve to property values or page variables are currently supported. Support for more complex expressions involving boolean or other operators may be added in the future.

Static Properties
Attributes representing static properties are handled similarly to static property elements and use a similar syntax. For example, the earlier G r i d P a n emarkup shown earlier to demonstrate static property elements could be rewritten as follows:
< G r i d P a n e > < c h i l d r e n > < L a b e lt e x t = " M yL a b e l "G r i d P a n e . r o w I n d e x = " 0 "G r i d P a n e . c o l u m n I n d e x = " 0 " / > < / c h i l d r e n > < / T a b P a n e >

In addition to being more concise, static property attributes, like instance property attributes, support location, resource, and variable resolution operators, the only limitation being that it is not possible to create an expression binding to a static property.

Event Handlers
Event handler attributes are a convenient means of attaching behaviors to document elements. Any class that defines as e t O n E v e n t ( )method can be assigned an event handler in markup, as can any observable property (via an "onPropertyChange" attribute). FXML supports two types of event handler attributes: script event handlers and controller method event handlers. Each are discussed below.

Script Event Handlers


A script event handler is an event handler that executes script code when the event is fired, similar to event handlers in HTML. For example, the following script-based handler for the button's "onAction" event uses JavaScript to write the text "You clicked me!" to the console when the user presses the button:
< ? l a n g u a g ej a v a s c r i p t ? > . . . < V B o x >
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 9/15

06/08/13

Introduction to FXML | JavaFX 2.2

< c h i l d r e n > < B u t t o nt e x t = " C l i c kM e ! " o n A c t i o n = " j a v a . l a n g . S y s t e m . o u t . p r i n t l n ( ' Y o uc l i c k e dm e ! ' ) ; " / > < / c h i l d r e n > < / V B o x >

Note the use of the language processing instruction at the beginning of the code snippet. This PI tells the FXML loader which scripting language should be used to execute the event handler. A page language must be specified whenever inline script is used in an FXML document, and can only be specified once per document. However, this does not apply to external scripts, which may be implemented using any number of supported scripting languages. Scripting is discussed in more detail in the next section.

Controller Method Event Handlers


A controller method event handler is a method defined by a document's "controller". A controller is an object that is associated with the deserialized contents of an FXML document and is responsible for coordinating the behaviors of the objects (often user interface elements) defined by the document. A controller method event handler is specified by a leading hash symbol followed by the name of the handler method. For example:
< V B o xf x : c o n t r o l l e r = " c o m . f o o . M y C o n t r o l l e r " x m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < c h i l d r e n > < B u t t o nt e x t = " C l i c kM e ! "o n A c t i o n = " # h a n d l e B u t t o n A c t i o n " / > < / c h i l d r e n > < / V B o x >

Note the use of the f x : c o n t r o l l e rattribute on the root element. This attribute is used to associate a controller class with the document. If M y C o n t r o l l e ris defined as follows:
p a c k a g ec o m . f o o ; p u b l i cc l a s sM y C o n t r o l l e r{ p u b l i cv o i dh a n d l e B u t t o n A c t i o n ( A c t i o n E v e n te v e n t ){ S y s t e m . o u t . p r i n t l n ( " Y o uc l i c k e dm e ! " ) ; } }

the h a n d l e B u t t o n A c t i o n ( )will be called when the user presses the button, and the text "You clicked me!" will be written to the console. In general, a handler method should conform to the signature of a standard event handler; that is, it should take a single argument of a type that extends j a v a f x . e v e n t . E v e n tand should return void (similar to an event delegate in C#). The event argument often carries important and useful information about the nature of the event; however, it is optional and may be omitted if desired. Controllers are discussed in more detail in a later section.

Scripting
The < f x : s c r i p t >tag allows a caller to import scripting code into or embed script within a FXML file. Any JVM scripting language can be used, including JavaScript, Groovy, and Clojure, among others. Script code is often used to define event handlers directly in markup or in an associated source file, since event handlers can often be written more concisely in more loosely-typed scripting languages than they can in a statically-typed language such as Java. For example, the following markup defines a function called h a n d l e B u t t o n A c t i o n ( )that is called by the action handler attached to the B u t t o nelement:
< ? l a n g u a g ej a v a s c r i p t ? > < ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < ? i m p o r tj a v a f x . s c e n e . l a y o u t . * ? > < V B o xx m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < f x : s c r i p t >
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 10/15

06/08/13

Introduction to FXML | JavaFX 2.2

i m p o r t C l a s s ( j a v a . l a n g . S y s t e m ) ; f u n c t i o nh a n d l e B u t t o n A c t i o n ( e v e n t ){ S y s t e m . o u t . p r i n t l n ( ' Y o uc l i c k e dm e ! ' ) ; } < / f x : s c r i p t > < c h i l d r e n > < B u t t o nt e x t = " C l i c kM e ! "o n A c t i o n = " h a n d l e B u t t o n A c t i o n ( e v e n t ) ; " / > < / c h i l d r e n > < / V B o x >

Clicking the button triggers the event handler, which invokes the function, producing output identical to the previous examples. Script code may also be defined in external files. The previous example could be split into an FXML file and a JavaScript source file with no difference in functionality: example.fxml
< ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < ? i m p o r tj a v a f x . s c e n e . l a y o u t . * ? > < V B o xx m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < f x : s c r i p ts o u r c e = " e x a m p l e . j s " / > < c h i l d r e n > < B u t t o nt e x t = " C l i c kM e ! "o n A c t i o n = " h a n d l e B u t t o n A c t i o n ( e v e n t ) ; " / > < / c h i l d r e n > < / V B o x >

example.js
i m p o r t C l a s s ( j a v a . l a n g . S y s t e m ) ; f u n c t i o nh a n d l e B u t t o n A c t i o n ( e v e n t ){ S y s t e m . o u t . p r i n t l n ( ' Y o uc l i c k e dm e ! ' ) ; }

It is often preferable to separate code from markup in this way, since many text editors support syntax highlighting for the various scripting languages supported by the JVM. It can also help improve readability of the source code and markup. Note that script blocks are not limited to defining event handler functions. Script code is executed as it is processed, so it can also be used to dynamically configure the structure of the resulting output. As a simple example, the following FXML includes a script block that defines a variable named "labelText". The value of this variable is used to populate the text property of a L a b e linstance:
< f x : s c r i p t > v a rm y T e x t=" T h i si st h et e x to fm yl a b e l . " ; < / f x : s c r i p t > . . . < L a b e lt e x t = " $ m y T e x t " / >

Controllers
While it can be convenient to write simple event handlers in script, either inline or defined in external files, it is often preferable to define more complex application logic in a compiled, strongly-typed language such as Java. As discussed earlier, the f x : c o n t r o l l e rattribute allows a caller to associate a "controller" class with an FXML document. A controller is a compiled class that implements the "code behind" the object hierarchy defined by the document. As shown earlier, controllers are often used to implement event handlers for user interface elements defined in markup:
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 11/15

06/08/13

Introduction to FXML | JavaFX 2.2

< V B o xf x : c o n t r o l l e r = " c o m . f o o . M y C o n t r o l l e r " x m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < c h i l d r e n > < B u t t o nt e x t = " C l i c kM e ! "o n A c t i o n = " # h a n d l e B u t t o n A c t i o n " / > < / c h i l d r e n > < / V B o x > p a c k a g ec o m . f o o ; p u b l i cc l a s sM y C o n t r o l l e r{ p u b l i cv o i dh a n d l e B u t t o n A c t i o n ( A c t i o n E v e n te v e n t ){ S y s t e m . o u t . p r i n t l n ( " Y o uc l i c k e dm e ! " ) ; } }

In many cases, it is sufficient to simply declare event handlers in this manner. However, when more control over the behavior of the controller and the elements it manages is required, the controller can define an i n i t i a l i z e ( ) method, which will be called once on an implementing controller when the contents of its associated document have been completely loaded:
p u b l i cv o i di n i t i a l i z e ( ) ;

This allows the implementing class to perform any necessary post-processing on the content. It also provides the controller with access to the resources that were used to load the document and the location that was used to resolve relative paths within the document (commonly equivalent to the location of the document itself). For example, the following code defines an i n i t i a l i z e ( )method that attaches an action handler to a button in code rather than via an event handler attribute, as was done in the previous example. The button instance variable is injected by the loader as the document is read. The resulting application behavior is identical:
< V B o xf x : c o n t r o l l e r = " c o m . f o o . M y C o n t r o l l e r " x m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < c h i l d r e n > < B u t t o nf x : i d = " b u t t o n "t e x t = " C l i c kM e ! " / > < / c h i l d r e n > < / V B o x > p a c k a g ec o m . f o o ; p u b l i cc l a s sM y C o n t r o l l e ri m p l e m e n t sI n i t i a l i z a b l e{ p u b l i cB u t t o nb u t t o n ; @ O v e r r i d e p u b l i cv o i di n i t i a l i z e ( U R Ll o c a t i o n ,R e s o u r c e sr e s o u r c e s ) b u t t o n . s e t O n A c t i o n ( n e wE v e n t H a n d l e r < A c t i o n E v e n t > ( ){ @ O v e r r i d e p u b l i cv o i dh a n d l e ( A c t i o n E v e n te v e n t ){ S y s t e m . o u t . p r i n t l n ( " Y o uc l i c k e dm e ! " ) ; } } ) ; } }

@FXML
Note that, in the previous examples, the controller member fields and event handler methods were declared as public so they can be set or invoked by the loader. In practice, this is not often an issue, since a controller is generally only visible to the FXML loader that creates it. However, for developers who prefer more restricted visibility for controller fields or handler methods, the j a v a f x . f x m l . F X M Lannotation can be used. This annotation marks a protected or private class member as accessible to FXML. For example, the controllers from the previous examples could be rewritten as follows:
p a c k a g ec o m . f o o ; p u b l i cc l a s sM y C o n t r o l l e r{ @ F X M L p r i v a t ev o i dh a n d l e B u t t o n A c t i o n ( A c t i o n E v e n te v e n t ){ S y s t e m . o u t . p r i n t l n ( " Y o uc l i c k e dm e ! " ) ;
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 12/15

06/08/13

Introduction to FXML | JavaFX 2.2

} } p a c k a g ec o m . f o o ; p u b l i cc l a s sM y C o n t r o l l e ri m p l e m e n t sI n i t i a l i z a b l e{ @ F X M Lp r i v a t eB u t t o nb u t t o n ; @ F X M L p r o t e c t e dv o i di n i t i a l i z e ( ) b u t t o n . s e t O n A c t i o n ( n e wE v e n t H a n d l e r < A c t i o n E v e n t > ( ){ @ O v e r r i d e p u b l i cv o i dh a n d l e ( A c t i o n E v e n te v e n t ){ S y s t e m . o u t . p r i n t l n ( " Y o uc l i c k e dm e ! " ) ; } } ) ; } }

In the first version, the h a n d l e B u t t o n A c t i o n ( )is tagged with @ F X M Lto allow markup defined in the controller's document to invoke it. In the second example, the button field is annotated to allow the loader to set its value. The i n i t i a l i z e ( )method is similarly annotated. Note that the @ F X M Lannotation can currently only be used with trusted code. Because the FXML loader relies on reflection to set member fields and invoke member methods, it must call s e t A c c e s s i b l e ( )on any non-public F i e l d . s e t A c c e s s i b l e ( )is a privileged operation that can only be executed in a secure context. This may change in a future release.

Nested Controllers
Controller instances for nested FXML documents loaded via the < f x : i n c l u d e >element are mapped directly to member fields of the including controller. This allows a developer to easily access functionality defined by an include (such as a dialog window presented by an application's main window controller). For example, given the following code: main_window_content.fxml
< V B o xf x : c o n t r o l l e r = " c o m . f o o . M a i n C o n t r o l l e r " > < f x : i n c l u d ef x : i d = " d i a l o g "s o u r c e = " d i a l o g . f x m l " / > . . . < / V B o x >

MainController.java
p u b l i cc l a s sM a i n C o n t r o l l e re x t e n d sC o n t r o l l e r{ @ F X M Lp r i v a t eW i n d o wd i a l o g ; @ F X M Lp r i v a t eD i a l o g C o n t r o l l e rd i a l o g C o n t r o l l e r ; . . . }

when the controller's i n i t i a l i z e ( )method is called, the d i a l o gfield will contain the root element loaded from the "dialog.fxml" include, and the d i a l o g C o n t r o l l e rfield will contain the include's controller. The main controller can then invoke methods on the included controller, to populate and show the dialog, for example.

FXMLLoader
The F X M L L o a d e rclass is responsible for actually loading an FXML source file and returning the resulting object graph. For example, the following code loads an FXML file from a location on the classpath relative to the loading class and localizes it with a resource bundle named "com.foo.example". The type of the root element is assumed to be a subclass of j a v a f x . s c e n e . l a y o u t . P a n e , and the document is assumed to define a controller of type M y C o n t r o l l e r :
U R Ll o c a t i o n=g e t C l a s s ( ) . g e t R e s o u r c e ( " e x a m p l e . f x m l " ) ; R e s o u r c e B u n d l er e s o u r c e s=R e s o u r c e B u n d l e . g e t B u n d l e ( " c o m . f o o . e x a m p l e " ) ;
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 13/15

06/08/13

Introduction to FXML | JavaFX 2.2

F X M L L o a d e rf x m l L o a d e r=n e wF X M L L o a d e r ( l o c a t i o n ,r e s o u r c e s ) ; P a n er o o t=( P a n e ) f x m l L o a d e r . l o a d ( ) ; M y C o n t r o l l e rc o n t r o l l e r=( M y C o n t r o l l e r ) f x m l L o a d e r . g e t C o n t r o l l e r ( ) ;

Note that the output of an F X M L L o a d e r # l o a d ( )operation is an instance hierarchy that reflects the actual named classes in the document, not o r g . w 3 c . d o mnodes representing those classes. Internally, F X M L L o a d e ruses the j a v a x . x m l . s t r e a mAPI (also known as the Streaming API for XML, or StAX) to load an FXML document. StAX is an extremely efficient event-based XML parsing API that is conceptually similar to its W3C predecessor, SAX. It allows an FXML document to be processed in a single pass, rather than loaded into an intermediate DOM structure and then post-processed.

Custom Components
The s e t R o o t ( )and s e t C o n t r o l l e r ( )methods of F X M L L o a d e rallow a caller to inject document root and controller values, respectively, into the document namespace, rather than delegating creation of these values to F X M L L o a d e r itself. This allows a developer to easily create reusable controls that are internally implemented using markup, but (from an API perspective) appear identically to controls implemented programmatically. For example, the following markup defines the structure of a simple custom control containing a T e x t F i e l dand a B u t t o ninstance. The root container is defined as an instance of j a v a f x . s c e n e . l a y o u t . V B o x :
< ? i m p o r tj a v a f x . s c e n e . * ? > < ? i m p o r tj a v a f x . s c e n e . c o n t r o l . * ? > < ? i m p o r tj a v a f x . s c e n e . l a y o u t . * ? > < f x : r o o tt y p e = " j a v a f x . s c e n e . l a y o u t . V B o x "x m l n s : f x = " h t t p : / / j a v a f x . c o m / f x m l " > < T e x t F i e l df x : i d = " t e x t F i e l d " / > < B u t t o nt e x t = " C l i c kM e "o n A c t i o n = " # d o S o m e t h i n g " / > < / f x : r o o t >

As mentioned earlier, the < f x : r o o t >tag creates a reference to a previously defined root element. The value of this element is obtained by calling the g e t R o o t ( )method of F X M L L o a d e r . Prior to calling l o a d ( ) , the caller must specify this value via a call to s e t R o o t ( ) . The caller may similarly provide a value for the document's controller by calling s e t C o n t r o l l e r ( ) , which sets the value that will be used as the document's controller when the document is read. These two methods are commonly used together when creating custom FXML-based components. In the following example, the C u s t o m C o n t r o lclass extends V B o x(the type declared by the < f x : r o o t >element), and sets itself as both the root and controller of the FXML document in its constructor. When the document is loaded, the contents of C u s t o m C o n t r o lwill be populated with the contents of the previous FXML document:
p a c k a g ef x m l ; i m p o r tj a v a . i o . I O E x c e p t i o n ; i m p o r tj a v a f x . b e a n s . p r o p e r t y . S t r i n g P r o p e r t y ; i m p o r tj a v a f x . f x m l . F X M L ; i m p o r tj a v a f x . f x m l . F X M L L o a d e r ; i m p o r tj a v a f x . s c e n e . c o n t r o l . T e x t F i e l d ; i m p o r tj a v a f x . s c e n e . l a y o u t . V B o x ; p u b l i cc l a s sC u s t o m C o n t r o le x t e n d sV B o x{ @ F X M Lp r i v a t eT e x t F i e l dt e x t F i e l d ; p u b l i cC u s t o m C o n t r o l ( ){ F X M L L o a d e rf x m l L o a d e r=n e wF X M L L o a d e r ( g e t C l a s s ( ) . g e t R e s o u r c e ( " c u s t o m _ c o n t r o l . f x m l " ) ) ; f x m l L o a d e r . s e t R o o t ( t h i s ) ; f x m l L o a d e r . s e t C o n t r o l l e r ( t h i s ) ; t r y{ f x m l L o a d e r . l o a d ( ) ; }c a t c h( I O E x c e p t i o ne x c e p t i o n ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e x c e p t i o n ) ; } } p u b l i cS t r i n gg e t T e x t ( ){ r e t u r nt e x t P r o p e r t y ( ) . g e t ( ) ;
docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html 14/15

06/08/13

Introduction to FXML | JavaFX 2.2

} p u b l i cv o i ds e t T e x t ( S t r i n gv a l u e ){ t e x t P r o p e r t y ( ) . s e t ( v a l u e ) ; } p u b l i cS t r i n g P r o p e r t yt e x t P r o p e r t y ( ){ r e t u r nt e x t F i e l d . t e x t P r o p e r t y ( ) ; } @ F X M L p r o t e c t e dv o i dd o S o m e t h i n g ( ){ S y s t e m . o u t . p r i n t l n ( " T h eb u t t o nw a sc l i c k e d ! " ) ; } }

Now, callers can use instances of this control in code or in markup, just like any other control; e.g.: Java
H B o xh b o x=n e wH B o x ( ) ; C u s t o m C o n t r o lc u s t o m C o n t r o l=n e wC u s t o m C o n t r o l ( ) ; c u s t o m C o n t r o l . s e t T e x t ( " H e l l oW o r l d ! " ) ; h b o x . g e t C h i l d r e n ( ) . a d d ( c u s t o m C o n t r o l ) ;

FXML
< H B o x > < C u s t o m C o n t r o lt e x t = " H e l l oW o r l d ! " / > < / H B o x >
Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms.

docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html

15/15

Potrebbero piacerti anche