/
introduction_to_fxml.html
1113 lines (856 loc) · 59.2 KB
/
introduction_to_fxml.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<!--
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-->
<html lang="en">
<head>
<link href="fxml.css" type="text/css" rel="stylesheet"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Introduction to FXML | JavaFX @FXVERSION@</title>
<meta name="description" content="The document introduces FXML, an XML-based declarative markup language for defining user interfaces in JavaFX @FXVERSION@ applications."/>
<meta name="keywords" content="JavaFX, FXML, JavaFX GUI development, web development, Java application development, GUI applications, rich internet applications, RIA, expressive content"/>
</head>
<body>
<div class="fx-code-header">
<div class="version"><br/>Release: JavaFX @FXVERSION@</div>
</div>
<h1>Introduction to FXML</h1>
<p class="subtitle">Last updated: 01 May 2017</p>
<h2>Contents</h2>
<ul class="contents">
<li><a href="#overview">Overview</a></li>
<li>
<a href="#elements">Elements</a>
<ul>
<li>
<a href="#class_instance_elements">Class Instance Elements</a>
<ul>
<li><a href="#instance_declaration_elements">Instance Declarations</a></li>
<li><a href="#include_elements"><fx:include></a></li>
<li><a href="#constant_elements"><fx:constant></a></li>
<li><a href="#reference_elements"><fx:reference></a></li>
<li><a href="#copy_elements"><fx:copy></a></li>
<li><a href="#root_elements"><fx:root></a></li>
</ul>
</li>
<li>
<a href="#property_elements">Property Elements</a>
<ul>
<li><a href="#property_setter_elements">Property Setters</a></li>
<li><a href="#read_only_list_property_elements">Read-Only List Properties</a></li>
<li><a href="#read_only_map_property_elements">Read-Only Map Properties</a></li>
<li><a href="#default_properties">Default Properties</a></li>
</ul>
</li>
<li><a href="#static_property_elements">Static Properties</a></li>
<li><a href="#define_elements">Define Blocks</a></li>
</ul>
</li>
<li>
<a href="#attributes">Attributes</a>
<ul>
<li>
<a href="#instance_property_attributes">Instance Properties</a>
<ul>
<li><a href="#location_resolution">Location Resolution</a></li>
<li><a href="#resource_resolution">Resource Resolution</a></li>
<li><a href="#variable_resolution">Variable Resolution</a></li>
<li><a href="#escape_sequences">Escape Sequences</a></li>
<li><a href="#expression_binding">Expression Binding</a></li>
</ul>
</li>
<li><a href="#static_property_attributes">Static Properties</a></li>
<li>
<a href="#event_handler_attributes">Event Handlers</a>
<ul>
<li><a href="#script_event_handlers">Script Event Handlers</a></li>
<li><a href="#controller_method_event_handlers">Controller Method Event Handlers</a></li>
<li><a href="#expression_handlers">Event handlers from expressions</a></li>
<li><a href="#collections_and_property_handlers">Special handlers for collections and properties</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#scripting">Scripting</a></li>
<li>
<a href="#controllers">Controllers</a>
<ul>
<li><a href="#fxml_annotation">@FXML</a></li>
<li><a href="#nested_controllers">Nested Controllers</a></li>
</ul>
</li>
<li>
<a href="#fxmlloader">FXMLLoader</a>
<ul>
<li><a href="#custom_components">Custom Components</a></li>
</ul>
</li>
<li><a href="#deploy_as_module">Deploying an Application as a Module</a></li>
</ul>
<h2><a id="overview">Overview</a></h2>
<p>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.</p>
<p>This document introduces the FXML markup language and explains how it can be used to simplify development of JavaFX applications.</p>
<h2><a id="elements">Elements</a></h2>
<p>In FXML, an XML element represents one of the following:</p>
<ul>
<li>A class instance</li>
<li>A property of a class instance</li>
<li>A "static" property</li>
<li>A "define" block</li>
<li>A block of script code</li>
</ul>
<p>Class instances, instance properties, static properties, and define blocks are discussed in this section below. Scripting is discussed in a later section.</p>
<h3><a id="class_instance_elements">Class Instance Elements</a></h3>
<p>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.</p>
<h4><a id="instance_declaration_elements">Instance Declarations</a></h4>
<p>If an element's tag is considered an instance declaration if the tag begins with uppercase letter (and the class is imported) or, as in Java, it denotes a fully-qualified (including the package name) name of a class. When the FXML loader (also introduced later) encounters such an element, it creates an instance of that class.</p>
<p>Importing a class is done using the "import" processing instruction (PI). For example, the following PI imports the <span class="code">javafx.scene.control.Label</span> class into the current FXML document’s namespace:</p>
<pre class="code">
<?import javafx.scene.control.Label?>
</pre>
<p>This PI imports all classes from the javafx.scene.control package into the current namespace:</p>
<pre class="code">
<?import javafx.scene.control.*?>
</pre>
<p>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 <span class="code">javafx.scene.control.Label</span> and sets its "text" property to "Hello, World!":</p>
<pre class="code">
<?import javafx.scene.control.Label?>
<Label text="Hello, World!"/>
</pre>
<p>Note that the <span class="code">Label</span>’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.</p>
<p>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.</p>
<h5>Maps</h5>
<p>Internally, the FXML loader uses an instance of <span class="code">com.sun.javafx.fxml.BeanAdapter</span> to wrap an instantiated object and invoke its setter methods. This (currently) private class implements the <span class="code">java.util.Map</span> interface and allows a caller to get and set Bean property values as key/value pairs.</p>
<p>If an element represents a type that already implements <span class="code">Map</span> (such as <span class="code">java.util.HashMap</span>), it is not wrapped and its <span class="code">get()</span> and <span class="code">put()</span> methods are invoked directly. For example, the following FXML creates an instance of <span class="code">HashMap</span> and sets its "foo" and "bar" values to "123" and "456", respectively:
<pre class="code">
<HashMap foo="123" bar="456"/>
</pre>
<h5>fx:value</h5>
<p>The <span class="code">fx:value</span> attribute can be used to initialize an instance of a type that does not have a default constructor but provides a static <span class="code">valueOf(String)</span> method. For example, <span class="code">java.lang.String</span> as well as each of the primitive wrapper types define a <span class="code">valueOf()</span> method and can be constructed in FXML as follows:</p>
<pre class="code">
<String fx:value="Hello, World!"/>
<Double fx:value="1.0"/>
<Boolean fx:value="false"/>
</pre>
<p>Custom classes that define a static <span class="code">valueOf(String)</span> method can also be constructed this way.</p>
<h5>fx:factory</h5>
<p>The <span class="code">fx:factory</span> attribute 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:</p>
<pre class="code">
<FXCollections fx:factory="observableArrayList">
<String fx:value="A"/>
<String fx:value="B"/>
<String fx:value="C"/>
</FXCollections>
</pre>
<h5>Builders</h5>
<p>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.</p>
<p>Builder support in FXML is provided by two interfaces. The <span class="code">javafx.util.Builder</span> interface defines a single method named <span class="code">build()</span> which is responsible for constructing the actual object:</p>
<pre class="code">
public interface Builder<T> {
public T build();
}
</pre>
<p>A <span class="code">javafx.util.BuilderFactory</span> is responsible for producing builders that are capable of instantiating a given type:</p>
<pre class="code">
public interface BuilderFactory {
public Builder<?> getBuilder(Class<?> type);
}
</pre>
<p>A default builder factory, <span class="code">JavaFXBuilderFactory</span>, is provided in the <span class="code">javafx.fxml</span> package. 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 <span class="code">javafx.scene.paint.Color</span> class:
<pre class="code">
<Color red="1.0" green="0.0" blue="0.0"/>
</pre>
<p>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:</p>
<pre class="code">
<Color>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</Color>
</pre>
<p>The <span class="code">Color</span> instance cannot be fully constructed until all three of the color components are known.</p>
<p>When processing markup for an object that will be constructed by a builder, the <span class="code">Builder</span> instances are treated like value objects - if a <span class="code">Builder</span> implements the <span class="code">Map</span> interface, the <span class="code">put()</span> method is used to set the builder's attribute values. Otherwise, the builder is wrapped in a <span class="code">BeanAdapter</span> and its properties are assumed to be exposed via standard Bean setters.</p>
<h4><a id="include_elements"><fx:include></a></h4>
<p>The <span class="code"><fx:include></span> tag creates an object from FXML markup defined in another file. It is used as follows:</p>
<pre class="code">
<fx:include source="<span class="variable">filename</span>"/>
</pre>
<p>where <span class="variable">filename</span> 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.</p>
<p>For example, given the following markup:</p>
<pre class="code">
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns:fx="http://javafx.com/fxml">
<children>
<fx:include source="my_button.fxml"/>
</children>
</VBox>
</pre>
<p>If <span class="filename">my_button.fxml</span> contains the following:
<pre class="code">
<?import javafx.scene.control.*?>
<Button text="My Button"/>
</pre>
<p>the resulting scene graph would contain a <span class="code">VBox</span> as a root object with a single <span class="code">Button</span> as a child node.</p>
<p>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.</p>
<p><span class="code"><fx:include></span> 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.</p>
<pre class="code">
<fx:include source="<span class="variable">filename</span>" resources="<span class="variable">resource_file</span>" charset="utf-8"/>
</pre>
<h4><a id="constant_elements"><fx:constant></a></h4>
<p>The <span class="code"><fx:constant></span> element creates a reference to a class constant. For example, the following markup sets the value of the "minWidth" property of a<span class="code">Button</span> instance to the value of the <span class="code">NEGATIVE_INFINITY</span> constant defined by the <span class="code">java.lang.Double</span> class:</p>
<pre class="code">
<Button>
<minHeight><Double fx:constant="NEGATIVE_INFINITY"/></minHeight>
</Button>
</pre>
<h4><a id="reference_elements"><fx:reference></a></h4>
<p>The <span class="code"><fx:reference></span> 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 <span class="code">fx:id</span> attribute or with a script variables, both of which are discussed in more detail in later sections. The "source" attribute of the <span class="code"><fx:reference></span> element specifies the name of the object to which the new element will refer.</p>
<p>For example, the following markup assigns a previously-defined <span class="code">Image</span> instance named "myImage" to the "image" property of an <span class="code">ImageView</span> control:</p>
<pre class="code">
<ImageView>
<image>
<fx:reference source="myImage"/>
</image>
</ImageView>
</pre>
<p>Note that, since it is also possible to dereference a variable using the attribute variable resolution operator (discussed later in the <a href="#attributes">Attributes</a> section), <span class="code">fx:reference</span> is generally only used when a reference value must be specified as an element, such as when adding the reference to a collection:</p>
<pre class="code">
<ArrayList>
<fx:reference source="element1"/>
<fx:reference source="element2"/>
<fx:reference source="element3"/>
</ArrayList>
</pre>
<p>For most other cases, using an attribute is simpler and more concise.</p>
<h4><a id="copy_elements"><fx:copy></a></h4>
<p>The <span class="code"><fx:copy></span> element creates a copy of an existing element. Like <span class="code"><fx:reference></span>, 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.</p>
<p>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.</p>
<h4><a id="root_elements"><fx:root></a></h4>
<p>The <span class="code"><fx:root></span> element creates a reference to a previously defined root element. It is only valid as the root node of an FXML document. <span class="code"><fx:root></span> is used primarily when creating custom controls that are backed by FXML markup. This is discussed in more detail in the <a href="#fxmlloader">FXMLLoader</a> section.</p>
<h3><a id="property_elements">Property Elements</a></h3>
<p>Elements whose tag names begin with a lowercase letter represent object properties. A property element may represent one of the following:</p>
<ul>
<li>A property setter</li>
<li>A read-only list property</li>
<li>A read-only map property</li>
</ul>
<h4><a id="property_setter_elements">Property Setters</a></h4>
<p>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.</p>
<p>For example, the following FXML creates an instance of the <span class="code">Label</span> class and sets the value of the label's "text" property to "Hello, World!":</p>
<pre class="code">
<?import javafx.scene.control.Label?>
<Label>
<text>Hello, World!</text>
</Label>
</pre>
<p>This produces the same result as the earlier example which used an attribute to set the "text" property:</p>
<pre class="code">
<?import javafx.scene.control.Label?>
<Label text="Hello, World!"/>
</pre>
<p>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.</p>
<h5>Type Coercion</h5>
<p>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.</p>
<p>The FXML loader uses the <span class="code">coerce()</span> method of <span class="code">BeanAdapter</span> to perform any required type conversions. This method is capable of performing basic primitive type conversions such as <span class="code">String</span> to <span class="code">boolean</span> or <span class="code">int</span> to <span class="code">double</span>, and will also convert <span class="code">String</span> to <span class="code">Class</span> or <span class="code">String</span> to <span class="code">Enum</span>. Additional conversions can be implemented by defining a static <span class="code">valueOf()</span> method on the target type.</p>
<h4><a id="read_only_list_property_elements">Read-Only List Properties</a></h4>
<p>A read-only list property is a Bean property whose getter returns an instance of <span class="code">java.util.List</span> and has no corresponding setter method. The contents of a read-only list element are automatically added to the list as they are processed.</p>
<p>For example, the "children" property of <span class="code">javafx.scene.Group</span> is a read-only list property representing the group's child nodes:</p>
<pre class="code">
<?import javafx.scene.*?>
<?import javafx.scene.shape.*?>
<Group xmlns:fx="http://javafx.com/fxml">
<children>
<Rectangle fx:id="rectangle" x="10" y="10" width="320" height="240"
fill="#ff0000"/>
...
</children>
</Group>
</pre>
<p>As each sub-element of the <span class="code"><children></span> element is read, it is added to the list returned by <span class="code">Group#getChildren()</span>.
<h4><a id="read_only_map_property_elements">Read-Only Map Properties</a></h4>
<p>A read-only map property is a bean property whose getter returns an instance of <span class="code">java.util.Map</span> and has no corresponding setter method. The attributes of a read-only map element are applied to the map when the closing tag is processed.</p>
<p>The "properties" property of <span class="code">javafx.scene.Node</span> is an example of a read-only map property. The following markup sets the "foo" and "bar" properties of a <span class="code">Label</span> instance to "123" and "456", respectively:</p>
<pre class="code">
<?import javafx.scene.control.*?>
<Button>
<properties foo="123" bar="456"/>
</Button>
</pre>
<p>Note that a read-only property whose type is neither a <span class="code">List</span> nor a <span class="code">Map</span> will be treated as if it were a read-only map. The return value of the getter method will be wrapped in a <span class="code">BeanAdapter</span> and can be used in the same way as any other read-only map.</p>
<h4><a id="default_properties">Default Properties</a></h4>
<p>A class may define a "default property" using the <span class="code">@DefaultProperty</span> annotation defined in the <span class="code">javafx.beans</span> package. If present, the sub-element representing the default property can be omitted from the markup.</p>
<p>For example, since <span class="code">javafx.scene.layout.Pane</span> (the superclass of <span class="code">javafx.scene.layout.VBox</span>) defines a default property of "children", a <span class="code"><children></span> element is not required; the loader will automatically add the sub-elements of the <span class="code">VBox</span> to the container's "children" collection:</p>
<pre class="code">
<?import javafx.scene.*?>
<?import javafx.scene.shape.*?>
<VBox xmlns:fx="http://javafx.com/fxml">
<Button text="Click Me!"/>
...
</VBox>
</pre>
<p>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.</p>
<p>For example, since <span class="code">javafx.scene.control.ScrollPane</span> defines a default property of "content", a scroll pane containing a <span class="code">TextArea</span> as its content can be specified as follows:
<pre class="code">
<ScrollPane>
<TextArea text="Once upon a time..."/>
</ScrollPane>
</pre>
<p>Taking advantage of default properties can significantly reduce the verbosity of FXML markup.</p>
<h3><a id="static_property_elements">Static Properties</a></h3>
<p>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).</p>
<p>Static properties are prefixed with the name of class that defines them. For example, The following FXML invokes the static setter for <span class="code">GridPane</span>'s "rowIndex" and "columnIndex" properties:</p>
<pre class="code">
<GridPane>
<children>
<Label text="My Label">
<GridPane.rowIndex>0</GridPane.rowIndex>
<GridPane.columnIndex>0</GridPane.columnIndex>
</Label>
</children>
</TabPane>
</pre>
<p>This translates roughly to the following in Java:</p>
<pre class="code">
GridPane gridPane = new GridPane();
Label label = new Label();
label.setText("My Label");
GridPane.setRowIndex(label, 0);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
</pre>
<p>
The calls to <span class="code">GridPane#setRowIndex()</span> and <span class="code">GridPane#setColumnIndex()</span> "attach" the index data to the <span class="code">Label</span> instance. <span class="code">GridPane</span> then uses these during layout to arrange its children appropriately. Other containers, including <span class="code">AnchorPane</span>, <span class="code">BorderPane</span>, and <span class="code">StackPane</span>, define similar properties.</p>
<p>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.</p>
<h3><a id="define_elements">Define Blocks</a></h3>
<p>The <span class="code"><fx:define></span> element is used to create objects that exist outside of the object hierarchy but may need to be referred to elsewhere.</p>
<p>For example, when working with radio buttons, it is common to define a <span class="code">ToggleGroup</span> that 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:</p>
<pre class="code">
<VBox>
<fx:define>
<ToggleGroup fx:id="myToggleGroup"/>
</fx:define>
<children>
<RadioButton text="A" toggleGroup="$myToggleGroup"/>
<RadioButton text="B" toggleGroup="$myToggleGroup"/>
<RadioButton text="C" toggleGroup="$myToggleGroup"/>
</children>
</VBox>
</pre>
<p>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.</p>
<h2><a id="attributes">Attributes</a></h2>
<p>An attribute in FXML may represent one of the following:</p>
<ul>
<li>A property of a class instance</li>
<li>A "static" property</li>
<li>An event handler</li>
</ul>
<p>Each are discussed in more detail in the following sections.</p>
<h3><a id="instance_property_attributes">Instance Properties</a></h3>
<p>Like property elements, attributes can also be used to configure the properties of a class instance. For example, the following markup creates a <span class="code">Button</span> whose text reads "Click Me!":</p>
<pre class="code">
<?import javafx.scene.control.*?>
<Button text="Click Me!"/>
</pre>
<p>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 <span class="code">Color</span>:</p>
<pre class="code">
<Rectangle fx:id="rectangle" x="10" y="10" width="320" height="240"
fill="#ff0000"/>
</pre>
<p>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 <span class="code">TabPane</span> control, which can't be set until all of the tabs have been added).</p>
<p>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:</p>
<ul>
<li>Location resolution</li>
<li>Resource resolution</li>
<li>Variable resolution</li>
</ul>
<h4><a id="location_resolution">Location Resolution</a></h4>
<p>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.</p>
<p>For example, the following markup creates an ImageView and populates it with image data from <span class="filename">my_image.png</span>, which is assumed to be located at a path relative to the current FXML file:</p>
<pre class="code">
<ImageView>
<image>
<Image url="@my_image.png"/>
</image>
</ImageView>
</pre>
<p>Since <span class="code">Image</span> is an immutable object, a builder is required to construct it. Alternatively, if <span class="code">Image</span> were to define a <span class="code">valueOf(URL)</span> factory method, the image view could be populated as follows:</p>
<pre class="code">
<ImageView image="@my_image.png"/>
</pre>
<p>The value of the "image" attribute would be converted to a URL by the FXML loader, then coerced to an <span class="code">Image</span> using the <span class="code">valueOf()</span> method.</p>
<p>Note that whitespace values in the URL must be encoded; for example, to refer to a file named "My Image.png", the FXML document should contain the following:</p>
<pre class="code">
<Image url="@My%20Image.png"/>
</pre>
<p>rather than:</p>
<pre class="code">
<Image url="@My Image.png"/>
</pre>
<h4><a id="resource_resolution">Resource Resolution</a></h4>
<p>In FXML, resource substitution can be performed at load time for localization purposes. When provided with an instance of <span class="code">java.util.ResourceBundle</span>, the FXML loader will replace instances of resource names with their locale-specific values. Resource names are identified by a "%" prefix, as shown below:</p>
<pre class="code">
<Label text="%myText"/>
</pre>
<p>If the loader is given a resource bundle defined as follows:</p>
<pre class="code">
myText = This is the text!
</pre>
<p>the output of the FXML loader would be a <span class="code">Label</span> instance containing the text "This is the text!".</p>
<h4><a id="variable_resolution">Variable Resolution</a></h4>
<p>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:</p>
<pre class="code">
<fx:define>
<ToggleGroup fx:id="myToggleGroup"/>
</fx:define>
...
<RadioButton text="A" toggleGroup="$myToggleGroup"/>
<RadioButton text="B" toggleGroup="$myToggleGroup"/>
<RadioButton text="C" toggleGroup="$myToggleGroup"/>
</pre>
<p>Assigning an <span class="code">fx:id</span> value 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 <span class="code">setId()</span> method.</p>
<h4><a id="escape_sequences">Escape Sequences</a></h4>
<p>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 <span class="code">Label</span> instance whose text reads "$10.00":</p>
<pre class="code">
<Label text="\$10.00"/>
</pre>
<h4><a id="expression_binding">Expression Binding</a></h4>
<p>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.</p>
<p>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 <span class="code">Label</span> instance:</p>
<pre class="code">
<TextField fx:id="textField"/>
<Label text="${textField.text}"/>
</pre>
<p>As the user types in the text input, the label's text content will be automatically updated.</p>
<p>More complex expression are also supported. A list of supported constants and operators follows:</p>
<table>
<caption>Constants and Operators Table</caption>
<tr><th scope="col">Constant / Operator</th><th scope="col">Description</th></tr>
<tr><th scope="row">"string"<br />'string'</th><td>A string constant</td></tr>
<tr><th scope="row">true<br />false</th><td>A boolean constant</td></tr>
<tr><th scope="row">null</th><td>A constant representing the null value</td></tr>
<tr><th scope="row">50.0<br />3e5<br />42</th><td>A numerical constant</td></tr>
<tr><th scope="row">- <br/>(unary operator)</th><td>Unary minus operator, applied on a number</td>
<tr><th scope="row">! <br/>(unary operator)</th><td>Unary negation of a boolean</td></tr>
<tr><th scope="row">+ - <br />
* /
%</th> <td>Numerical binary operators</td></tr>
<tr><th scope="row">&& ||</th><td>Boolean binary operators</td></tr>
<tr><th scope="row">> >= <br />
< <= <br />
== !=</th>
<td>Binary operators of comparison.<br/> Both arguments must be of type Comparable</td></tr>
</table>
<h3><a id="static_property_attributes">Static Properties</a></h3>
<p>Attributes representing static properties are handled similarly to static property elements and use a similar syntax. For example, the earlier <span class="code">GridPane</span> markup shown earlier to demonstrate static property elements could be rewritten as follows:</p>
<pre class="code">
<GridPane>
<children>
<Label text="My Label" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
</children>
</TabPane>
</pre>
<p>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.</p>
<h3><a id="event_handler_attributes">Event Handlers</a></h3>
<p>Event handler attributes are a convenient means of attaching behaviors to document elements. Any class that defines a <span class="code">setOn<span class="variable">Event</span>()</span> method can be assigned an event handler in markup.</p>
<p>FXML supports three types of event handler attributes: script event handlers, controller method event handlers and expressions. Each are discussed below.</p>
<h4><a id="script_event_handlers">Script Event Handlers</a></h4>
<p>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:</p>
<pre class="code">
<?language javascript?>
...
<VBox>
<children>
<Button text="Click Me!"
onAction="java.lang.System.out.println('You clicked me!');"/>
</children>
</VBox>
</pre>
<p>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.</p>
<p>Note: to turn off automatic compilation of script code place the processing instruction <span class="code"><?compile false?></span> before the element that contains the script. To turn on compilation of script code again use the processing instruction <span class="code"><?compile true?></span> (or short: <span class="code"><?compile?></span>). The compile processing instruction can be used repeatedly to turn compilation of script code off and on.</p>
<h4><a id="controller_method_event_handlers">Controller Method Event Handlers</a></h4>
<p>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.</p>
<p>A controller method event handler is specified by a leading hash symbol followed by the name of the handler method. For example:</p>
<pre class="code">
<VBox fx:controller="com.foo.MyController"
xmlns:fx="http://javafx.com/fxml">
<children>
<Button text="Click Me!" onAction="#handleButtonAction"/>
</children>
</VBox>
</pre>
<p>Note the use of the <span class="code">fx:controller</span> attribute on the root element. This attribute is used to associate a controller class with the document. If <span class="code">MyController</span> is defined as follows:</p>
<pre class="code">
package com.foo;
public class MyController {
public void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
}
}
</pre>
<p>the <span class="code">handleButtonAction()</span> will be called when the user presses the button, and the text "You clicked me!" will be written to the console.</p>
<p>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 <span class="code">javafx.event.Event</span> and 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.
So this is also a valid handler:</p>
<pre class="code">
package com.foo;
public class MyController {
public void handleButtonAction() {
System.out.println("You clicked me!");
}
}
</pre>
<p>Controllers are discussed in more detail in a later section.</p>
<h4><a id="expression_handlers">Event handlers from expressions</a></h4>
<p>Any expression that point to a <a href="#variable_resolution">variable</a> of javafx.event.EventHandler type
can be used as an expression handler. </p>
<p>
Previous example using an expression handler:
</p>
<pre class="code">
<VBox fx:controller="com.foo.MyController"
xmlns:fx="http://javafx.com/fxml">
<children>
<Button text="Click Me!" onAction="$controller.onActionHandler"/>
</children>
</VBox>
</pre>
<p> With the controller that contains a field like this </p>
<pre class="code">
public class MyController {
@FXML
public EventHandler<ActionEvent> onActionHandler = new EventHandler<>() { ... }
...
}
</pre>
<p> Note that other kinds of expressions, like <a href="#expression_binding">binding expressions</a>
are not supported in this context. </p>
<h4><a id="collections_and_property_handlers">Special handlers for collections and properties</a></h4>
<p> Collections and object properties cannot be listen to using <span class="code">setOn<span class="variable">Event</span>()</span> methods.
For these reason, special handler methods need to be used.
<span class="code">ObservableList</span>, <span class="code">ObservableMap</span> or <span class="code">ObservableSet</span>
uses a special <span class="code">onChange</span> attribute that points to a handler method with a <span class="code">ListChangeListener.Change</span>, <span class="code">MapChangeListener.Change</span> or <span class="code">SetChangeListener.Change</span> parameter, respectively.
</p>
<pre class="code">
<VBox fx:controller="com.foo.MyController"
xmlns:fx="http://javafx.com/fxml">
<children onChange="#handleChildrenChange"/>
</VBox>
</pre>
where the handler method looks like this:
<pre class="code">
package com.foo;
import javafx.collections.ListChangeListener.Change;
public class MyController {
public void handleChildrenChange(ListChangeListener.Change c) {
System.out.println("Children changed!");
}
}
</pre>
<p>Similarly, the property handlers are methods that have the same parameters as changed method of ChangeListener :</p>
<p><span class="code">changed(ObservableValue<? extends T> observable, T oldValue, T newValue)</span></p>
<p>A handler for parent property would look like this</p>
<pre class="code">
public class MyController {
public void handleParentChange(ObservableValue value, Parent oldValue, Parent newValue) {
System.out.println("Parent changed!");
}
}
</pre>
<p>For convenience, the first parameter can be a subclass of <span class="code">ObservableValue</span>,
e.g. <span class="code">Property</span></p>
<p>For registering to a property, a special <span class="code">on<propertyName>Change</span>
attribute must be used.</p>
<pre class="code">
<VBox fx:controller="com.foo.MyController"
xmlns:fx="http://javafx.com/fxml" onParentChange="#handleParentChange"/>
</pre>
<p>Note that collections and properties do not currently support scripting handlers.</p>
<h2><a id="scripting">Scripting</a></h2>
<p>
The <span class="code"><fx:script></span> 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.</p>
<p>Scripts are compiled by default, when they are first loaded, if the <span class="code">ScriptEngine</span> implements the <span class="code">javax.script.Compilable</span> interface. If compilation fails, the <span class="code">FXMLLoader</span> will fall back to interpreted mode.</p>
<p>Note: to turn off automatic compilation of script code place the processing instruction <span class="code"><?compile false?></span> before the script element. To turn on compilation of script code again use the processing instruction <span class="code"><?compile true?></span> (or short: <span class="code"><?compile?></span>). The compile processing instruction can be used repeatedly to turn compilation of script code off and on.</p>
<p>The following example markup defines a function called <span class="code">handleButtonAction()</span> that is called by the action handler attached to the <span class="code">Button</span> element:</p>
<pre class="code">
<?language javascript?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns:fx="http://javafx.com/fxml">
<fx:script>
function handleButtonAction(event) {
java.lang.System.out.println('You clicked me!');
}
</fx:script>
<children>
<Button text="Click Me!" onAction="handleButtonAction(event);"/>
</children>
</VBox>
</pre>
<p>Clicking the button triggers the event handler, which invokes the function, producing output identical to the previous examples.</p>
<p>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:</p>
<div class="caption">example.fxml</div>
<pre class="code">
<?language javascript?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns:fx="http://javafx.com/fxml">
<fx:script source="example.js" charset="cp1252"/>
<children>
<Button text="Click Me!" onAction="handleButtonAction(event);"/>
</children>
</VBox>
</pre>
<div class="caption">example.js</div>
<pre class="code">
function handleButtonAction(event) {
java.lang.System.out.println('You clicked me!');
}
</pre>
<p>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.</p>
<p>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 <span class="code">Label</span> instance:</p>
<pre class="code">
<fx:script>
var myText = "This is the text of my label.";
</fx:script>
...
<Label text="$myText"/>
</pre>
<p><strong>Warning:</strong> As of JavaFX 8, <span class="code">importClass()</span> javascript function is no longer supported. You have to use fully qualified names as in the example above or load a nashorn compatibility script.</p>
<pre class="code">
load("nashorn:mozilla_compat.js");
importClass(java.lang.System);
function handleButtonAction(event) {
System.out.println('You clicked me!');
}
</pre>
<h2><a id="controllers">Controllers</a></h2>
<p>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 <span class="code">fx:controller</span> attribute 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.</p>
<p>As shown earlier, controllers are often used to implement event handlers for user interface elements defined in markup:</p>
<pre class="code">
<VBox fx:controller="com.foo.MyController"
xmlns:fx="http://javafx.com/fxml">
<children>
<Button text="Click Me!" onAction="#handleButtonAction"/>
</children>
</VBox>
</pre>
<pre class="code">
package com.foo;
public class MyController {
public void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
}
}
</pre>
<p>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 <span class="code">initialize()</span> method, which will be called once on an implementing controller when the contents of its associated document have been completely loaded:</p>
<pre class="code">
public void initialize();
</pre>
<p>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).</p>
<p>For example, the following code defines an <span class="code">initialize()</span> 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:</p>
<pre class="code">
<VBox fx:controller="com.foo.MyController"
xmlns:fx="http://javafx.com/fxml">
<children>
<Button fx:id="button" text="Click Me!"/>
</children>
</VBox>
</pre>
<pre class="code">
package com.foo;
public class MyController implements Initializable {
public Button button;
@Override
public void initialize(URL location, Resources resources)
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("You clicked me!");
}
});
}
}
</pre>
<h3><a id="fxml_annotation">@FXML</a></h3>
<p>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 <span
class="code">javafx.fxml.FXML</span> annotation can be used. This
annotation marks a protected or private class member as accessible
to FXML.
If the class being annotated is in a named module, the
module containing that class must <span class="code">open</span>
the containing package to at least
the <span class="code">javafx.fxml</span> module.</p>
<p>For example, the controllers from the previous examples could be rewritten as follows:</p>
<pre class="code">
package com.foo;
public class MyController {
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
}
}
</pre>
<pre class="code">
package com.foo;
public class MyController implements Initializable {
@FXML private Button button;
@FXML
protected void initialize()
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("You clicked me!");
}
});
}
}
</pre>
<p>In the first version, the <span class="code">handleButtonAction()</span> is tagged with <span class="code">@FXML</span> to 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 <span class="code">initialize()</span> method is similarly annotated.</p>
<h3><a id="nested_controllers">Nested Controllers</a></h3>
<p>Controller instances for nested FXML documents loaded via the <span class="code"><fx:include></span> 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:
<div class="caption">main_window_content.fxml</div>
<pre class="code">
<VBox fx:controller="com.foo.MainController">
<fx:define>
<fx:include fx:id="dialog" source="dialog.fxml"/>
</fx:define>
...
</VBox>
</pre>
<div class="caption">MainController.java</div>
<pre class="code">
public class MainController extends Controller {
@FXML private Window dialog;
@FXML private DialogController dialogController;
...
}
</pre>
<p>when the controller's <span class="code">initialize()</span> method is called, the <span class="code">dialog</span> field will contain the root element loaded from the "dialog.fxml" include, and the <span class="code">dialogController</span> field 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. Note that as the content of the file referenced by fx:include otherwise would become part of the scene graph spanned from main_window_content.fxml, it is necessary to wrap fx:include by fx:define to separate the scene graphs of both windows.</p>
<h2><a id="fxmlloader">FXMLLoader</a></h2>
<p>The <span class="code">FXMLLoader</span> class 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 <span class="code">javafx.scene.layout.Pane</span>, and the document is assumed to define a controller of type <span class="code">MyController</span>:</p>
<pre class="code">
URL location = getClass().getResource("example.fxml");
ResourceBundle resources = ResourceBundle.getBundle("com.foo.example");
FXMLLoader fxmlLoader = new FXMLLoader(location, resources);
Pane root = (Pane)fxmlLoader.load();
MyController controller = (MyController)fxmlLoader.getController();