Script Part9 PDF
Script Part9 PDF
Script Part9 PDF
A program intended for interactive use may provide a large number of user interface (UI) components,
as shown here:
The UI shown above is implemented using Java Swing and all the menu items, buttons, labels, tree
views etc. are implemented in procedual code; all items are created, layouted and have functionality
associated with them using Java code.
The perferred way to build a UI in the context of JavaFX is not to use to procedual code but rather
to specify the UI using FXML.
FXML features1 :
11.1 FXML
FXML provides elements for representing:
• class instances
• properties of class instances
• “static properties”
• “define blocks“
• scriptable code
In the following we discuss some of the main features of FXML, with the goal of getting a basic
understanding of how FXML operates.
We will be using an interactive tool called SceneBuilder to create FXML files.
1
This chapter is based on: Introducing FXML - A Markup Language for JavaFX, Greg Brown, 8/15/2011, http:
//fxexperience.com/wp-content/uploads/2011/08/Introducing-FXML.pdf
Advanced Java for Bioinformatics, WS’17/18, D. Huson, December 21, 2017 47
• referencing or copying existing instances, e.g. from included external FXML files
For example, a Label object with the text “Hello World!” can be constructed as follows:
<j a v a f x . s c e n e . c o n t r o l . L a b e l t e x t=” H e l l o , World ! ”/>
or
<?import j 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 , World ! ”/>
FXML supports more advanced constructs as well. For example, if you want to setup a HashMap and
provide some entries, then that can be done as follows:
<HashMap peptideA=”AVVLPVLVAVAC” peptideB=”GGGHGHGEEGEC”/>
This will create a map with two key-value pairs: (peptideA,AVVLPVLVAVAC) and
(peptideB,GGGHGHGEEGEC).
Classes that provide a valueOf() method can be inialized as shown in these examples:
<S t r i n g f x : v a l u e=” H e l l o , World ! ”/>
<Double f x : v a l u e=” 1 . 0 ”/>
<Boolean f x : v a l u e=” f a l s e ”/>
FXML supports the use of “factories” and “builders” to setup instances of classes. For example, the
following produces a color object:
<C o l o r r e d=” 1 . 0 ” g r e e n=” 0 . 0 ” b l u e=” 0 . 0 ”/>
11.1.2 Properties
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, like
this:
<?import j a v a f x . s c e n e . c o n t r o l . L a b e l?>
<Label>
<t e x t >H e l l o , World! </ t e x t >
</Label>
FXML uses “type coercion” to convert property values to the appropriate type as needed.
This is required because XML only supports elements, text and attributes with text values.
However, Java supports a number of different data types including built- in primitive value types as
well as extensible reference types.
For example, based on type coercion, this works as intended:
<R e c t a n g l e x=” 10 ” y=” 10 ” width=” 320 ” h e i g h t=” 240 ”
f i l l =”#f f 0 0 0 0 ”/>
The result is a Rectangle object with the given dimensions and fill color.
FXML provides a mechanism for adding elements to a list, for example, this adds children to a group:
48 Advanced Java for Bioinformatics, WS’17/18, D. Huson, December 21, 2017
<Group>
<c h i l d r e n >
<R e c t a n g l e f x : i d=” r e c t a n g l e ” x=” 10 ” y=” 10 ” width=” 320 ”
h e i g h t=” 240 ” f i l l =”#f f 0 0 0 0 ”/>
...
</ c h i l d r e n >
</Group>
Additionally, if the corresponding object’s type has an id property, then the value will be passed to
the objects setId() method.
To distinguish a binding from a simple setting of the property, the variable name must be enclosed by
curly brackets (after the variable resolution operator $).
• A script event handler defines the functionality in the FXML file using a scripting language.
• A controller event handler is provided by the Java controller class (discussed below) associated
with the FXML document and the functionality is implemented in Java.
The script part of this construct can be placed in a separate file (called clickme.js, say), to keep the
code separate from the markup for better readability.
For more complex functionality, it is preferable to implement this in your Java program.
The attribute fx:controller allows one to associate a “controller” class with an FXML document.
This class implements the code that corresponds to the object hierarchy defined in the FXML docu-
ment.
Here is a simple example of a controller class:
package mypackage ;
public c l a s s M y C o n t r o l l e r {
public void h a n d l e B u t t o n A c t i o n ( ActionEvent e v e n t ) {
System . out . p r i n t l n ( ”You c l i c k e d me ! ” ) ;
}
}
Clicking on the button will cause the Java method handleButtonAction(event) to be called and the
text You clicked me! to be written to the console.
This method gets called once the FXML document has been parsed and allows the program to initialize
stuff.
This is useful in the context of instance variable injection.
For example, consider this FXML code:
<VBox f x : c o n t r o l l e r=”myPackage . M y C o n t r o l l e r ”
xmlns : f x=” h t t p : / / j a v a f x . com/ fxml ”>
<c h i l d r e n >
<Button f x : i d=” button ” t e x t=” C l i c k Me ! ”/>
</ c h i l d r e n >
</VBox>
Here, an identifier fx:id=button is assigned to the button and it can be used in the controller class
to access the button. If the controller class contains a Button member field called button and when
the controller is constructed by the FXML loader, then a reference to the button is “injected” into
the variable.
This allows the following code to work:
package myPackage ;
public c l a s s M y C o n t r o l l e r implements I n i t i a l i z a b l e {
public Button button ; // w i l l g e t i n j e c t e d
@Override
public void i n i t i a l i z e (URL l o c a t i o n , R e s o u r c e s r e s o u r c e s )
button . setOnAction (new EventHandler<ActionEvent >() {
@Override
public void h a n d l e ( ActionEvent e v e n t ) {
System . out . p r i n t l n ( ”You c l i c k e d me ! ” ) ;
} });
In this example, the button must be declared as a public member field to allow injection.
However, we generally do not want to allow direct access to member fields. (This is the second issue.)
To allow injection into private member fields, one can use the FXML annotation:
package myPackage ;
public c l a s s M y C o n t r o l l e r implements I n i t i a l i z a b l e {
@FXML
private Button button ;
@Override
public void i n i t i a l i z e (URL l o c a t i o n , R e s o u r c e s r e s o u r c e s )
button . setOnAction (new EventHandler<ActionEvent >() {
@Override
public void h a n d l e ( ActionEvent e v e n t ) {
System . out . p r i n t l n ( ”You c l i c k e d me ! ” ) ;
} });
}
}
Advanced Java for Bioinformatics, WS’17/18, D. Huson, December 21, 2017 51
Here is an example that shows how the FXML file is loaded and how one can access the corresponding
controller object. Note that in this example all three files are contained in the same package:
public c l a s s BlastProgram extends A p p l i c a t i o n {
@Override
public void s t a r t ( S t a g e p r i m a r y S t a g e ) throws E x c e p t i o n {
FXMLLoader fxmlLoader=new FXMLLoader ( ) ;
Parent r o o t ;
try ( InputStream i n s=g e t C l a s s ( )
. g e t R e s o u r c e ( ” BlastProgram . fxml ” ) . openStream ( ) ) {
r o o t=fxmlLoader . l o a d ( i n s ) ;
}
B l a s t C o n t r o l l e r b l a s t C o n t r o l l e r=fxmlLoader . g e t C o n t r o l l e r ( ) ;
// can do s o m e t h i n g w i t h t h e c o n t r o l l e r h e r e . . .
p r i m a r y S t a g e . s e t S c e n e (new Scene ( r o o t , 8 0 0 , 6 0 0 ) ) ;
p r i m a r y S t a g e . s e t T i t l e ( ”NCBI B l a s t C l i e n t ” ) ;
p r i m a r y S t a g e . show ( ) ;
}
}
11.2 SceneBuilder
For the project, please use the program SceneBuilder to design your UI. You should use one FXML
file per window or complex dialog.
In the Model-View-Presenter pattern, your FXML files can be considered part of the View, whereas
your controller classes are part of the Presenter (or Controller in MVC).
Please name files so that it is clear how they belong together.
For example, if you are writing a program for viewing PDB files and the main program is implemented
in PDBViewer.java, then the FXML file defining the main GUI should be called PDBViewer.fxml and
the controller program should be called PDBViewerController.java.
Once you have an FXML file in your source tree and you have setup SceneBuilder correctly, then
Intellij will let you launch the program directly like this:
SceneBuilder is an interactive program for setting up your UI. It produces an FXML file as discussed
above.
This is what a simple project might look like in SceneBuilder:
52 Advanced Java for Bioinformatics, WS’17/18, D. Huson, December 21, 2017
Stuff to add
Contains Properties
layout
Controls
fx:id etc
Menu items of individual
Shapes Editable layout controls
etc
Hierarchy
Set controller here
This is how you define the fx:id for an element (in this case, the apply button). Select the item in
the left hand hierachical view, or in the center layout, and then use the bottom right panel to set the
variable:
The “Show Preview in Window” menu item allows you to test your UI:
The “Show Sample Controller Skeleton” menu item allows you to preview and copy the basic structure
of the controller file that should be associated with this FXML file:
Advanced Java for Bioinformatics, WS’17/18, D. Huson, December 21, 2017 53
11.3 CSS
What is CSS (Cascading Style Sheets)?2
• A language for describing the presentation of Web pages, including colors, layout, and fonts.
• It is independent of HTML and can be used with any XML-based markup language.
• The separation of HTML from CSS makes it easier to maintain sites, share style sheets across
pages, and tailor pages to different environments. Similar is true for seperation between pro-
gramming logic, FXML and CSS.
CSS can be used to determine the presentation of nodes in the JavaFX scene graph. There are three
issues to discuss:
. root {
−fx−f o n t −s i z e : 16 pt ;
−fx−f o n t −f a m i l y : ” C o u r i e r New” ;
−fx−b a s e : rgb ( 1 3 2 , 1 4 5 , 4 7 ) ;
−fx−background : rgb ( 2 2 5 , 2 2 8 , 2 0 3 ) ;
}
Here the selector is the root node of the scene graph and this style is applied to all nodes in the graph.
This code sets the color of a check box that has focus to golden:
. check−box : f o c u s e d {
−fx−c o l o r : g o l d e n ;
}
The SceneBuilder program allows one to define CSS for nodes in the FXML file.
For each Node, there are many different properties that can be styled using CSS, see the documentation
for details: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.
html
Here is an example of a styled dialog: