Você está na página 1de 100

Getting started with JavaFX

Introduction
JavaFX is the next step in the evolution of Java as a rich client platform. It is designed to
provide a lightweight, hardware-accelerated Java UI platform for enterprise client applications.
The latest release, JavaFX 2..2, represents a significant shift from previous releases.
!evelopers can now create JavaFX applications completel" in the Java programming language
with a fresh new set of #$I li%raries. There are a num%er of new features %eing introduced in
JavaFX 2. such as Java &wing integration, we% content integration, a hardware accelerated
graphics pipeline and new UI controls li%rar".
This '() will provide a crash course to help "ou get up and running with JavaFX 2..2 *uic+l".
,o prior experience in JavaFX is re*uired. #lthough a %asic +nowledge of the Java language
will surel" help. Join us and start creating stunning UI.
Prerequisites
This hands-on la% assumes "ou have some %asic +nowledge of or programming experience in,
the following technologies-
. Java language programming
System Requirements
JavaFX 2.0.2 System Requirements
Use the following information to ensure that "our operating s"stem, %rowser, and J!/ version
meet the re*uirements for running the JavaFX technolog". #lso included are the hardware
re*uirements for accelerated rendering of graphics.
Oerating Systems and !rowsers
0ou must run an operating s"stem and %rowser that are compati%le with JavaFX, as shown in
the following ta%le-
Oerating System "#2$!it and %&$!it' !rowsers "#2$!it and %&$!it'
1indows X$ 'ome and $rofessional with &ervice
$ac+ 2
Internet 3xplorer 4 and 5
6hrome
1indows 7ista 'ome 8asic, 'ome $remium,
8usiness, and Ultimate with &ervice $ac+ 2
Internet 3xplorer 4, 5, and 9
Firefox 2.:, 2.;, and <
6hrome
1indows 4 'ome $remium, $rofessional, and Ultimate Internet 3xplorer 5 and 9
Firefox 2.:, 2.;, and <
6hrome
Grahics Suort
0ou will notice an accelerated rendering of graphics in "our JavaFX applications if "our s"stem
has support for the new $rism hardware pipeline. The following ta%le lists the graphics cards
that have %een tested with $rism. If "our s"stem does not support $rism, then JavaFX uses the
Java2! software pipeline under $rism.
Grahics (ard Suorted Grahics Processing )nits "GP)s'
,7I!I# =o%ile >$Us- >eForce 5= and ?= series or higher,
,7& 2?= series or higher, and =o%ilit" @uadro FX
2= series or higher
!es+top >$Us- >eForce 5 and ? series or higher
1or+station >$Us- @uadro FX 2 series or higher
#TI =o%ile >$Us- =o%ilit" Aadeon '! 2, <, and
: series
!es+top >$Us- Aadeon '! 2<, 2, <, :,
and ; series
Intel =o%ile >$Us- >=# <:='! and >=# '!
!es+top >$Us- >=# <: and >=# '!
So*tware +eeded For ,his -a.
The following software should %e installed to participate in this la% exercises.
Java $latform BJ!/C 4u2 and
,et8eans 4.?
1e recommend "ou to use the %undle version-
J!/ 4u2 with ,et8eans4.?
-a. /0ercises
3xercise - &etting up "our environment
3xercise ?- >etting started with JavaFX, running and understanding "our first
application. B? minsC
3xercise 2- # %it of ever"thing B2 minsC
3xercise 2- Understanding )a"outs B? mins C
3xercise <- 3m%edded 8rowser B ? mins C
3xercise :- =edia B? minsC
1dditiona2 Resources
http-DDwww.oracle.comDEavafx
/0ercise 03 Setting u your environment
For this '() we are going to use the %undle version of the J!/ 4 update 2 and ,et%eans4.?
installer. )ets get startedF
First the welcome window will %e displa"ed, Eust go next.
The installer will perform the re*uired configurations.
#ccept an" agreement "ou get as+ed, and continue with the installation %" clic+ing on ,ext G
%utton.
&elect where "ou want to install the J!/. 0ou can change the suggested director" %" clic+ing
the 8rowse... %utton.
Then "ou need to select where "ou want to install the I!3. (ne more time, "ou could either
use the default director", or select a new one using the 8rowse %ottom.
The installer should %e a%le to find "our J!/ installation director", %ut if itHs not displa"ed,
please go to the 8rowse.. %utton to set it properl". &elect ,ext G
,ext, a summar" window gets displa"ed. $lease review it, and ma+e sure ever"thing loo+s
correct. If "ou notice an" error, "ou can clic+ on the I 8ac+ %utton, to go %ac+ and correct
an" issue. If ever"thing seems correct, clic+ on the Install %utton to start the installation
process.
1ait for the installation to finish.
#n installation summar" will %e displa"ed. =a+e sure the installation run successfull".
If "ou want to contri%ute to the ,et8eans proEect, please select the chec+%ox, and allow us to
improve the I!3 %" using general statistics a%out "our use of ,et8eans.
$lease start ,et8eans and ma+e sure it run without an" issues. The following image shows
the default screen once "ou start the tool.
8efore we go to exercise ?, we want to ma+e sure ever"thing got configured correctl". &o lets
chec+ few things-
6reate a new proEect-
0ou can do it so, %" clic+ing the new proEect icon
(r go to the menu and select File J ,ew $roEect option
# ,ew $roEect window should %e displa"ed. =a+e sure JavaFX is part of the 6ategories
listed.
3xpand the &amples section from the 6ategories list, and ma+e sure JavaFX 2 is also there.
6lic+ on 6ancel.
,ow "ou are read" to start having fun with JavaFX 2., lets move to exercise ?.
/0ercise 43 Getting started with JavaFX 2.05 running and understanding your *irst
a2ications. "40 mins'
This exercise will ta+e "ou through some of the ,et8eansH features to support JavaFX
development. 0ou will %e a%le to create "our first application without even t"ping an"
code.
6reate a new proEect-
(ption ?- Use the ,ew $roEect... icon
(ption 2- >o to the File menu and select ,ew $roEect option from there.
The ,ew $roEect window will appear. &elect-
6ategories- Java
$roEects- JavaFX #pplication
6lic+ on ,ext G
The ,ew JavaFX #pplication window will %e displa"ed.
Use an" name for "our $roEect ,ame
0ou can also select an" destination for "our new proEect location
=a+e sure the 6reate =ain 6lass option is selected
For "our convenience, select also the &et as =ain $roEect option
6lic+ Finish
0our new proEect will %e created and the main class will %e opened. !onHt worr"
too much a%out the code, as weHll stud" it in the next exercise. 8riefl" "ou can
notice a scene o%Eect, the container for "our UI components, it has a siKe of
2x2:. 0ou can also see a 8utton, with a L&a" H'ello 1orldHM text on it. Finall"
there is an event handler for the mouse action events, where we simpl" do a print
on the output window.

)ets run the proEect-
(ption ?- Use the Aun =ain $roEect icon
(ption 2- Aight clic+ on the proEect name and from the pop up menu select
Aun.
0our application will loo+ li+e this
6lic+ on the L'ello 1orldM %utton and notice the L'ello 1orldM string on the output
area.
JavaFX 2. plugin for ,et8eans also provides "ou with a %unch of pre-defined samples.
The" could %e ver" useful as starting point for learning JavaFX or simpl" to start "our
proEects, rather than creating an empt" one. )ets see how to use them.

6reate a new $roEect
The ,ew $roEect window gets displa"ed-
In the 6ategories section- expand &amples and select JavaFX 2
For proEect- select 6olorful6ircles
6lic+ on ,ext G
The ,ew 6olorful 6ircles window gets displa"ed-
)eave the default proEect name
6hoose an" destination director" for the proEect
6lic+ on Finish
(ne more time, we are not going to spend a lot of time at the code, we Eust want
to highlight a few things %efore we run the proEect.
1e have scene, in this case a %it %igger <9:x<5
1e create 2 different la"ers, and in each la"er we create a group of circles.
1e add some %lur effect to each la"er
1e create a rectangle, and instead of filling it with a plain color, we use a
linear gradient to have a nice effect.
1e put together the 2 la"ers, the previous rectangle an a newl" created
rectangle into a group, with a overla" %lending mode.
1e create an animation to move all the created circles around the screen.
1e run the animation
#nd finall" we run the whole application.
1. package colorfulcircles;
2.
3. import static java.lang.Math.random;
4. import java.util.ArrayList;
5. import java.util.List;
6. import javafx.animation.Animation;
7. import javafx.animation.KeyFrame;
8. import javafx.animation.KeyValue;
9. import javafx.animation.Timeline;
10. import javafx.application.Application;
11. import javafx.scene.Group;
12. import javafx.scene.Node;
13. import javafx.scene.Scene;
14. import javafx.scene.effect.BlendMode;
15. import javafx.scene.effect.BoxBlur;
16. import javafx.scene.paint.Color;
17. import javafx.scene.paint.CycleMethod;
18. import javafx.scene.paint.LinearGradient;
19. import javafx.scene.paint.Stop;
20. import javafx.scene.shape.Circle;
21. import javafx.scene.shape.Rectangle;
22. import javafx.scene.shape.StrokeType;
23. import javafx.stage.Stage;
24. import javafx.util.Duration;
25.
26. /**
27. * A sample that demonstrates how to draw and paint shapes, apply visual
28. * effects, blend colors in overlapping objects, and animate objects.
29. *
30. * @see javafx.scene.effect.BlendMode
31. * @see javafx.scene.effect.BoxBlur
32. * @see javafx.scene.shape.Circle
33. * @see javafx.scene.Group
34. * @see javafx.scene.paint.LinearGradient
35. * @see javafx.animation.Timeline
36. */
37. public class ColorfulCircles extends Application {
38. private static final double WIDTH = 495, HEIGHT = 480;
39. private Timeline animation;
40.
41. private void init(Stage primaryStage) {
42. Group root = new Group();
43. primaryStage.setResizable(false);
44. primaryStage.setScene(new Scene(root, 495,480));
45. Group layer1 = new Group();
46. for(int i=0; i<15;i++) {
47. Circle circle = new Circle(200,Color.web("white",0.05f));
48. circle.setStrokeType(StrokeType.OUTSIDE);
49. circle.setStroke(Color.web("white",0.2f));
50. circle.setStrokeWidth(4f);
51. layer1.getChildren().add(circle);
52. }
53. // create second list of circles
54. Group layer2 = new Group();
55. for(int i=0; i<20;i++) {
56. Circle circle = new Circle(70,Color.web("white",0.05f));
57. circle.setStrokeType(StrokeType.OUTSIDE);
58. circle.setStroke(Color.web("white",0.1f));
59. circle.setStrokeWidth(2f);
60. layer2.getChildren().add(circle);
61. }
62. // create third list of circles
63. Group layer3 = new Group();
64. for(int i=0; i<10;i++) {
65. Circle circle = new Circle(150,Color.web("white",0.05f));
66. circle.setStrokeType(StrokeType.OUTSIDE);
67. circle.setStroke(Color.web("white",0.16f));
68. circle.setStrokeWidth(4f);
69. layer3.getChildren().add(circle);
70. }
71. // Set a blur effect on each layer
72. layer1.setEffect(new BoxBlur(30,30,3));
73. layer2.setEffect(new BoxBlur(2,2,2));
74. layer3.setEffect(new BoxBlur(10,10,3));
75. // create a rectangle size of window with colored gradient
76. Rectangle colors = new Rectangle(WIDTH, HEIGHT,
77. new LinearGradient(0f,1f,1f,0f,true, CycleMethod.NO_CYCLE,
78. new Stop(0,Color.web("#f8bd55")),
79. new Stop(0.14f,Color.web("#c0fe56")),
80. new Stop(0.28f,Color.web("#5dfbc1")),
81. new Stop(0.43f,Color.web("#64c2f8")),
82. new Stop(0.57f,Color.web("#be4af7")),
83. new Stop(0.71f,Color.web("#ed5fc2")),
84. new Stop(0.85f,Color.web("#ef504c")),
85. new Stop(1,Color.web("#f2660f")))
86. );
87. colors.setBlendMode(BlendMode.OVERLAY);
88. // create main content
89. Group group = new Group(
90. new Rectangle(WIDTH, HEIGHT, Color.BLACK),
91. layer1,
92. layer2,
93. layer3,
94. colors
95. );
96. Rectangle clip = new Rectangle(WIDTH, HEIGHT);
97. clip.setSmooth(false);
98. group.setClip(clip);
99. root.getChildren().add(group);
100. // create list of all circles
101. List<Node> allCircles = new ArrayList<Node>();
102. allCircles.addAll(layer1.getChildren());
103. allCircles.addAll(layer2.getChildren());
104. allCircles.addAll(layer3.getChildren());
105. // Create a animation to randomly move every circle in allCircles
106. animation = new Timeline();
107. for(Node circle: allCircles) {
108. animation.getKeyFrames().addAll(
109. new KeyFrame(Duration.ZERO, // set start position at 0s
110. new KeyValue(circle.translateXProperty(),random()*WIDTH),
111. new KeyValue(circle.translateYProperty(),random()*HEIGHT)
112. ),
113. new KeyFrame(new Duration(40000), // set end position at 40s
114. new KeyValue(circle.translateXProperty(),random()*WIDTH),
115. new KeyValue(circle.translateYProperty(),random()*HEIGHT)
116. )
117. );
118. }
119. animation.setAutoReverse(true);
120. animation.setCycleCount(Animation.INDEFINITE);
121. }
122.
123. @Override public void stop() {
124. animation.stop();
125. }
126.
127. public void play() {
128. animation.play();
129. }
130.
131. @Override public void start(Stage primaryStage) throws Exception {
132. init(primaryStage);
133. primaryStage.show();
134. play();
135. }
136. public static void main(String[] args) { launch(args); }
137. }
Aun "our proEect
/0ercise 23 1 !it o* /verything
In this exercise we are going to create a small sample that tries to include some of the
coolest features of JavaFX 2.. 1e are going to use images, appl" transformations,
create animations and a lot of cool stuff.
Running the so2ution
First, lets run the solution. ItHs important to have a clear idea of what "ou will %e
%uilding.
The '() includes a solutions director" that contains a ,et8eans proEect with
the solution for each exercise. To open the solution proEect "ou have two
options-
(ption ?- 6lic+ on the (pen $roEect icon
(ption 2- From the File menu "ou can select the (pen $roEect option
In the (pen $roEect screen-
&elect the director" where "ou unKipped the '() file.
&elect the solutions director"
3xpands exercise2, and select the &ea#pp #pplication
6lic+ (pen $roEect
0ou should see &ea#pp in the $roEect list.
Aun the &ea#pp proEect-
(ption ?- 6lic+ the Aun $roEect icon
(ption 2- &elect &ea#pp proEect and right clic+ on it. From the popup menu
select Aun
0ou should see the app running.
=ove the mouse over the application and notice that a new image gets
displa"ed. In this exercise we are going to see how we can create animations to
manipulate the transparenc" of the UI o%Eects, and create nice transitions
%etween screens.
The two %ac+ground images B%lue sea and "ellow seaC are %ound with the mouse
enter and mouse exit events. )ets tr" now to move the mouse out of the
application one more time, and see how the %lue %ac+ground appear again as
"ou leave it. In this exercise, we will see how we can %ind the opacit" value of
those images to some properties associated to the mouse enter and exit events.
The x coordinate of the %ac+ground images are also %ound with mouse drag
events. Tr" this feature %" pressing the mouse, and dragging it along the x
coordinates. !rag it all the wa" to the end of the %ac+ground. ,otice that the
two shar+s at the top are a separate image, and this one is not %ind with the
mouse events, the" Eust sta" there as "ou drag the mouse. #gain "ou will learn
how to program all this.
6lic+ on the two shar+s, and see how the" swim awa". In this la% "ou will create
this animation, and associate it to get triggered %" the mouse clic+ events.
6lose the application %" clic+ing on the close icon. ,ow "ou are read" to start
creating this application.
Getting Started 6ith 7our 12ication
6reate a new JavaFX proEect called &ea#pp. 0ou can place it an" where "ou
want it, %ut it has to %e outside the solutions director". BFor detailed
instructions how to create a JavaFX 2. proEects, "ou can go %ac+ to exercise ?.C
8" default the generated code gets displa"ed, "ou should see something li+e
this-
4. ...
5. package seaapp;
6.
7. import javafx.application.Application;
8. import javafx.event.ActionEvent;
9. import javafx.event.EventHandler;
10. import javafx.scene.Scene;
11. import javafx.scene.control.Button;
12. import javafx.scene.layout.StackPane;
13. import javafx.stage.Stage;
14.
15. /**
16. *
17. * @author oracle
18. */
19.
20. public class SeaApp extends Application {
21.
22. /**
23. * @param args the command line arguments
24. */
25. public static void main(String[] args) {
26. launch(args);
27. }
28.
29. @Override
30. public void start(Stage primaryStage) {
31. primaryStage.setTitle("Hello World!");
32. Button btn = new Button();
33. btn.setText("Say 'Hello World'");
34. btn.setOnAction(new EventHandler<ActionEvent>() {
35.
36. @Override
37. public void handle(ActionEvent event) {
38. System.out.println("Hello World!");
39. }
40. });
41.
42. StackPane root = new StackPane();
43. root.getChildren().add(btn);
44. primaryStage.setScene(new Scene(root, 300, 250));
45. primaryStage.show();
46. }
47. }
Ta%le ?.
)ets stud" the generated code.
3ver" time "ou want to create a JavaFX application "ou have to extend the
Class Application. B&ee line 2
th
C
To launch "our JavaFX standalone application we use the method launch-
launch(args); B&ee line 2;
th
C. This method expects one parameter, the
arguments "ou need to provide to "our application. This method does not return
until the application has exited.
The main entr" point for all JavaFX applications is the start method. This
method is called after the init method has returned, and after the s"stem is read"
for the application to %egin running.
This method receive the primar" stage for this application, onto which the
application scene can %e set. 8efore we go an" further in this code, lets explain
a %it the scene graph programming model used %" JavaFX.
In JavaFX, all the UI content is structured as a scene graph. # scene graph is a
collection of nodes in a tree structure. # node ma" have man" children %ut often
onl" a single parent, with the effect of a parent applied to all its child nodesN an
operation performed on a group automaticall" propagates its effect to all of its
mem%ers. # common feature, for instance, is the a%ilit" to group related
shapesDo%Eects into a compound o%Eect that can then %e moved, transformed,
selected, etc. as easil" as a single o%Eect.
For JavaFX, the stage is the top-level container for the application, and the
scene is the drawing surface for the applicationHs content. The generated code
has a ver" simple structure, Eust a &tac+$ane for the root of the tree, and one
node, in this case a 8utton %tn.
)ine 2?
st
sets the stageHs title.
)ine 22
nd
creates a 8utton called %tn. )ines 22
rd
sets the text to %e displa"ed on it.
In lines 2<
th
- <
th
we create an event handler associated to the %uttonHs action. In
our case, we are Eust doing a simple printout L'ello 1orldM each time the %utton
gets clic+ed.
)ine <2
rd
is ver" important, once we create a node we need to add it to the scene
graph. In this case the %utton btn will go directl" in the root, so we need to add it
to it. &ee that we are adding this btn to the alread" existent rootHs children, in
our case our root doesnHt have an" children "et, %ut this is the wa" we alwa"s
add nodes in the scene graph tree.
)ine <<
th
creates the scene. ,otice that in the constructor we pass the root of the
tree, in this case the root is a &tac+$ane created in line <2
nd
. 0ou can also pass
in the sceneHs constructor the siKe of the displa" area and the %ac+ground color.
Finall" we set the stageHs scene.
1e show the stage B)ine <:
th
C.
Aun the sample. BIf "ou need details of how to run the sample, go %ac+ to
exercise ?C
6lic+ on the 8utton and see the L'ello 1orldM in the (utput area in ,et8eans.
6lose the application.
!elete lines 22
nd
to <
th,
and comment out the line <2
rd
. 0our &ea#pp.Eava class
should loo+ li+e this
If "ou canHt see the lines on the left hand side, right clic+ on that space, and
select L&how )ine ,um%ersM
Aight clic+ on the %ac+ground, and select LFix ImportsM, this will get rid of an"
unnecessar" imports we still have in the class.
,ow we are read" to start creating our new application.
First, we need some resources BimagesC for our proEect.
6lic+ on the 1indow menu, and then clic+ on favorites.
This will add a Favorites ta%, in "our proEect area
Aight clic+ in the FavoritesH white area, and select L#dd to Favorites...M
The L#dd to FavoritesM windows gets displa"ed. (pen the director" where
"ou unKip "our '() Kip file. (pen the LexercisesM director", and select
Lexercise2M. 6lic+ on the #dd %utton.
,ow "ou can see the Lexercise2M director" as part of the favoritesH list.
3xpands exercise2 J resources
&elect sea.Epg, sea?.Epg, shar+.png and closeIcon.png files.
Aight clic+ on them, and select cop".
,ow, lets go %ac+ to $roEects ta%.
3xpands &ea#pp J &ource $ac+ages J seaapp
Aight clic+ on seaapp and select ,ew J Java $ac+age
,ame it images, and clic+ Finish
Aight clic+ on images, and select paste.
,ow "ou can see "our resources B< imagesC as part of "our proEect.
,ow lets add the code to show an image. There are two classes "ou should %e
aware of- javafx.scene.image.Image and javafx.scene.image.ImageView.
The Image class represents graphical images and is used for loading images
from a specified UA). The ImageView is a Node used for painting images loaded
with Image class, and this is the one "ou add to the scene graph.
First we need to declare the ImageView varia%le
private ImageView sea0;
In the start method we can create the image-
1e need to create an Image, providing the location of the image to %e
displa"ed.
Then create an ImageView with the Image Eust created. The code should
loo+ li+e this-
sea0 = new ImageView(
new Image(SeaApp.class.getResourceAsStream("images/sea0.jpg")));
From the generated code "ou can notice that the root of the scene graph
is a &tac+$ane container. &tac+$ane la"s out its children in a %ac+-to-
front stac+, and it will position its children following the specified alignment
B$os.63,T3A %" defaultC. 8ecause we want to %e a%le to manipulate the
imageHs position, we are going to use a $ane as a main container.
6hange the line
StackPane root = new StackPane();
1ith the line
Pane root = new Pane();
,ote- 0ou can also reposition the &tac+$aneHs children using the
translation properties, %ut in our case we have decided to go with a $ane
and use the imageHs x and " properties.

,ow we need to add the Image7iew to the scene graph. The simplest
wa" is to add it to the root.
Uncomment the following line from "our code
//root.getChildren().add(btn);

#nd replace it with
root.getChildren().add(sea0);
0our code should loo+ li+e this-
,otice that line ?4
th,
29
th
and 2?
st
are highlighting some errors. This is %ecause
we are missing some imports. Aight clic+ on the %ac+ground and select LFix
imports...M
,et8eans might find more than one instance of Pane, Image and ImageView
class, and it will prompt "ou to select the correct ones. =a+e sure "ou select the
ones from javafx.scene.image pac+age.
0our code should loo+s li+e this
Aun "our application.
AesiKe the window to "our right, and notice that "our image is reall" long.
1e can set a 6lip area for this image. In our case we are going to use a
Aectangle with rounded corners.
!efine the clip. B#dd the following code after line 2
thC
private Rectangle seaClip0;
6reate the rectangle and set the rounded corners. B#dd the following code at
line 2<
th
C
seaClip0 = new Rectangle(300, 220);
seaClip0.setArcHeight(20);
seaClip0.setArcWidth(20);
&et the clip for the image. B#dd the following code at line 24
th
C
sea0.setClip(seaClip0);
Aight clic+ on the %ac+ground and select LFix imports...M. 1hen prompted
ma+e sure "ou select Rectangle from javafx.scene.shape pac+age.
0our code should now loo+ li+e this-
5. package seaapp;
6.
7. import javafx.application.Application;
8. import javafx.geometry.Pos;
9. import javafx.scene.Scene;
10. import javafx.scene.image.Image;
11. import javafx.scene.image.ImageView;
12. import javafx.scene.layout.Pane;
13. import javafx.scene.shape.Rectangle;
14. import javafx.stage.Stage;
15.
16. /**
17. *
18. * @author angie
19. */
20. public class SeaApp extends Application {
21. private ImageView sea0;
22. private Rectangle seaClip0;
23. /**
24. * @param args the command line arguments
25. */
26. public static void main(String[] args) {
27. launch(args);
28. }
29.
30. @Override
31. public void start(Stage primaryStage) {
32. primaryStage.setTitle("Hello World!");
33.
34. sea0 = new ImageView(new Image(SeaApp.class.
getResourceAsStream("images/sea0.jpg")));
35. seaClip0 = new Rectangle(300, 220);
36. seaClip0.setArcHeight(20);
37. seaClip0.setArcWidth(20);
38. sea0.setClip(seaClip0);
39. Pane root = new Pane();
40. root.getChildren().add(sea0);
41. primaryStage.setScene(new Scene(root, 300, 250));
42. primaryStage.show();
43. }
44. }
(ne cool tric+ "ou can do in "our application is to ma+e the stage transparent,
this means that the application wonHt have a window around the image. The
application will %lend nicel" with "our des+topHs %ac+ground.
Aemove line 22
nd
where "ou set the title for "ou window.
#dd the following line code
primaryStage.initStyle(StageStyle.TRANSPARENT);
Aeplace the following line
primaryStage.setScene(new Scene(root, 300, 250));
1ith
Scene scene = new Scene(root, 300, 250);
scene.setFill(null);
primaryStage.setScene(scene);
Aight clic+ on the %ac+ground and fix the imports
Aun the application and notice all the changes
,ow, the first issue we are facing is that we donHt have a close icon. Fortunatel"
"ou can use ,et8eans for this.
In the ,et8eansH ouput area, there is red s*uare, clic+ on this one to stop the
application.
Getting Started 6ith /vents
,ow, lets add another image, the exit icon. B!etailed steps at the %eginning of
exercise 2.C
!eclare an ImageView and call it quit
Inside the start method, create the quit ImageView.
The LXM image we are going to use is a %it %ig, so we need to ma+e sure it
has the siKe we want. &et the imageHs height and width to 2: Buse methods
setFitHeight, setFitWidthC
&et the imageHs x coordinate to 24 Buse method setXC
&et the imageHs " coordinate to ? Buse method setYC
=a+e sure "ou add quit to the scene graph, directl" to the root.
To add multiple children at the same time, use addAll method instead of
add, and provide all the nodes as parameters.
1e need to add some code to handle the mouse clic+ events on the quit Image.
8asicall", when the user clic+s on the image, we want the application to *uit.
quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
System.exit(0);
}
}));
1e need to call the method setOnMouseClicked to set the event handler for the
clic+ events. #s a parameter in our code we are providing an anon"mous
3vent'andler, and at the same time we are providing the method handle that
will %e invo+ed ever" time the *uit image gets a clic+.
#dding this piece of code will show some errors. =a+e sure "ou add the
re*uired imports Balso shown at the %eginning of this exercise.C
0our code should loo+ li+e this-
5. package seaapp;
6.
7. import javafx.application.Application;
8. import javafx.event.EventHandler;
9. import javafx.geometry.Pos;
10. import javafx.scene.Scene;
11. import javafx.scene.image.Image;
12. import javafx.scene.image.ImageView;
13. import javafx.scene.input.MouseEvent;
14. import javafx.scene.layout.Pane;
15. import javafx.scene.shape.Rectangle;
16. import javafx.stage.Stage;
17. import javafx.stage.StageStyle;
18.
19. /**
20. *
21. * @author angie
22. */
23. public class SeaApp extends Application {
24. private ImageView sea0;
25. private Rectangle seaClip0;
26. private ImageView quit;
27. /**
28. * @param args the command line arguments
29. */
30. public static void main(String[] args) {
31. launch(args);
32. }
33.
34. @Override
35. public void start(Stage primaryStage) {
36. primaryStage.initStyle(StageStyle.TRANSPARENT);
37.
38. sea0 = new ImageView(new Image(SeaApp.class.
getResourceAsStream("images/sea0.jpg")));
39. seaClip0 = new Rectangle(300, 220);
40. seaClip0.setArcHeight(20);
41. seaClip0.setArcWidth(20);
42. sea0.setClip(seaClip0);
43.
44. quit = new ImageView(new Image(SeaApp.class.
getResourceAsStream("images/closeIcon.png")));
45. quit.setFitHeight(25);
46. quit.setFitWidth(25);
47. quit.setX(270);
48. quit.setY(10);
49.
50. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
51. public void handle(MouseEvent me) {
52. System.exit(0);
53. }
54. }));
55. Pane root = new Pane();
56. root.getChildren().addAll(sea0,quit);
57. Scene scene = new Scene(root, 300, 250);
58. scene.setFill(null);
59. primaryStage.setScene(scene);
60. primaryStage.show();
61. }
62. }
Aun "our application.
6lic+ on the *uit image, and ma+e sure the application closes.
,ow, lets pla" a %it more with mouse events and %inding. 1e +now image sea0 is ver"
wide, and we are Eust seen a piece of it through the clip. 1hat we want to do, is %ind
the x coordinate of the image with the x coordinate of the mouse drag event. The result
will %e that as "ou drag the mouse the image will %e moving along with it.
)ets see our scenario-
There are few mouse events that get generated. First, there will %e a mouse pressed
event followed %" a num%er of mouse drag events. Finall", once "ou release "our
mouse, a mouse release event will %e generated. In our case we are interested in two
of these three events, mouse pressed and mouse dragged.
(n mouse pressed we need to find out the distance %etween the mouseEventX and the
original x coordinate of the image. 1e can call it &X. #s we drag the mouse around,
we need to +eep this distance, as we want the image to smoothl" move along with the
drag movement.
)ets see the code-
First we need to declare two varia%les, one will hold the real value of the imageHs
x coordinate and the second will hold the sX distance.
private double sX = 0;
private double coordXReal = 0;
,ow we need to implement setOnMousePressed and setOnMouseDragged for
sea0 ImageView. BThis code will go inside the start methodC
sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
sX = me.getSceneX() - coordXReal;
}
});
sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
coordXReal = me.getSceneX() - sX;
}
});
,ow, lets do some %inding. 8inding is a powerful mechanism for expressing direct
relationships %etween varia%les. 1hen o%Eects participate in %indings, changes made to
one o%Eect will automaticall" %e reflected in another o%Eect.
8indings are assem%led from one or more sources, +nown as dependencies. # %inding
o%serves its dependencies for changes and updates its own value according to changes
in the dependencies.
In JavaFX we normall" use $roperties as source of %indings. There are properties for
each primitive data t"pes, for example- SimpleDoubleProperty, SimpleFloat
Property, SimpleIntegerProperty, SimpleBooleanProperty, and also Simple
ObjectProperty and SimpleStringProperty.
)ets see the code-
(ur first though is to %ind sea0Hs x coordinate to coordXReal, %ut we need a
propert" for that, so lets convert coordXReal into a $ropert". 8ecause we are
using a dou%le value, we need to use a DoubleProperty.
6hange the line-
private double coordXReal = 0;
for this line-
private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
,ow update the event handlers as following-
sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
sX = me.getSceneX() - imageXProperty.getValue();
}
});
sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
imageXProperty.set(me.getSceneX() - sX);
}
});
,ow we are read" to add the %inding
sea0.xProperty().bind(imageXProperty);
3ver" time imageXProperty change, the x coordinate of sea0 gets updated.
0our code should loo+ li+e this-
5. package seaapp;
6.
7. import javafx.application.Application;
8. import javafx.beans.property.DoubleProperty;
9. import javafx.beans.property.SimpleDoubleProperty;
10. import javafx.event.EventHandler;
11. import javafx.scene.Scene;
12. import javafx.scene.image.Image;
13. import javafx.scene.image.ImageView;
14. import javafx.scene.input.MouseEvent;
15. import javafx.scene.layout.Pane;
16. import javafx.scene.shape.Rectangle;
17. import javafx.stage.Stage;
18. import javafx.stage.StageStyle;
19.
20. /**
21. *
22. * @author angie
23. */
24. public class SeaApp extends Application {
25. private ImageView sea0;
26. private Rectangle seaClip0;
27. private ImageView quit;
28. private double sX = 0;
29. private DoubleProperty imageXProperty =
new SimpleDoubleProperty(0);
30. /**
31. * @param args the command line arguments
32. */
33. public static void main(String[] args) {
34. launch(args);
35. }
36.
37. @Override
38. public void start(Stage primaryStage) {
39. primaryStage.initStyle(StageStyle.TRANSPARENT);
40.
41. sea0 = new ImageView(new Image(SeaApp.class.getResource .
AsStream("images/sea0.jpg")));
42. seaClip0 = new Rectangle(300, 220);
43. seaClip0.setArcHeight(20);
44. seaClip0.setArcWidth(20);
45. sea0.setClip(seaClip0);
46.
47. sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
48. public void handle(MouseEvent me) {
49. sX = me.getSceneX() - imageXProperty.getValue();
50. }
51. });
52.
53. sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
54. public void handle(MouseEvent me) {
55. imageXProperty.set(me.getSceneX() - sX);
56. }
57. });
58. sea0.xProperty().bind(imageXProperty);
59.
60. quit = new ImageView(new Image(SeaApp.class. GetResource
. AsStream("images/closeIcon.png")));
61. quit.setFitHeight(25);
62. quit.setFitWidth(25);
63. quit.setX(270);
64. quit.setY(10);
65.
66. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
67. public void handle(MouseEvent me) {
68. System.exit(0);
69. }
70. }));
71. Pane root = new Pane();
72. root.getChildren().addAll(sea0,quit);
73. Scene scene = new Scene(root, 300, 250);
74. scene.setFill(null);
75. primaryStage.setScene(scene);
76. primaryStage.show();
77. }
78. }
Aun the code and ma+e sure "ou can drag the mouse to move the image around.
Aemem%er we onl" %ind the x coordinates, so the imageHs movement is horiKontall".
8efore we continue with animations, lets organiKe the code a little %it.
&elect the lines where "ou create, modif" and set events to the *uit o%Eect. In
our case, itHs lines ;
th
- 4
th
Bdou%le chec+ with the image %elow, "ou might have
different line num%ersC.
Aight clic+ on the highlighted code, and select Aefactor J Introduce =ethod...
This will actuall" ta+e this code out of the start method, and put it into a
separate method, and replace all this code with the appropriate method call.
The LIntroduce =ethodM window will appear. 3nter setQuitButton for the
methodHs name, and clic+ o+.
Aeview the new code.
,ow, lets do the same refactoring process for setting up the mouse events in
sea0.
In our case, select lines <4
th
- :4
th

,ame the method settingUpDragging
0our code should loo+ li+e this-
1. package seaapp;
2.
3. import javafx.application.Application;
4. import javafx.beans.property.DoubleProperty;
5. import javafx.beans.property.SimpleDoubleProperty;
6. import javafx.event.EventHandler;
7. import javafx.scene.Scene;
8. import javafx.scene.image.Image;
9. import javafx.scene.image.ImageView;
10. import javafx.scene.input.MouseEvent;
11. import javafx.scene.layout.Pane;
12. import javafx.scene.shape.Rectangle;
13. import javafx.stage.Stage;
14. import javafx.stage.StageStyle;
15.
16. /**
17. *
18. * @author angie
19. */
20. public class SeaApp extends Application {
21. private ImageView sea0;
22. private Rectangle seaClip0;
23. private ImageView quit;
24. private double sX = 0;
25. private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
26. /**
27. * @param args the command line arguments
28. */
29. public static void main(String[] args) {
30. launch(args);
31. }
32.
33. @Override
34. public void start(Stage primaryStage) {
35. primaryStage.initStyle(StageStyle.TRANSPARENT);
36.
37. sea0 = new ImageView(new Image(SeaApp.class.getResource
AsStream("images/sea0.jpg")));
38. seaClip0 = new Rectangle(300, 220);
39. seaClip0.setArcHeight(20);
40. seaClip0.setArcWidth(20);
41. sea0.setClip(seaClip0);
42.
43. settingUpDragging();
44. sea0.xProperty().bind(imageXProperty);
45.
46. setQuitButton();
47.
48. Pane root = new Pane();
49. root.getChildren().addAll(sea0,quit);
50. Scene scene = new Scene(root, 300, 250);
51. scene.setFill(null);
52. primaryStage.setScene(scene);
53. primaryStage.show();
54. }
55.
56. private void settingUpDragging() {
57. sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
58. public void handle(MouseEvent me) {
59. sX = me.getSceneX() - imageXProperty.getValue();
60. }
61. });
62.
63. sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
64. public void handle(MouseEvent me) {
65. imageXProperty.set(me.getSceneX() - sX);
66. }
67. });
68. }
69.
70. private void setQuitButton() {
71. quit = new ImageView(new Image(SeaApp.class.getResource
AsStream("images/closeIcon.png")));
72. quit.setFitHeight(25);
73. quit.setFitWidth(25);
74. quit.setX(270);
75. quit.setY(10);
76.
77. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
78. public void handle(MouseEvent me) {
79. System.exit(0);
80. }
81. }));
82. }
83. }
,ow, lets add more UI components so we can pla" with animations.
#dd a new Image7iew, called sea1. sea1 is going to %e the same as sea0, %ut it
will displa" sea1.jpg.
6reate a new Rectangle, seaClip1, with the same specifications as seaClip0.
&et seaClip1 as the clip node for sea1.
8ind the sea1Hs x coordinate to imageXProperty
6reate the setOnMousePressed and setOnMouseDragged methods for sea1.
The will %e the same as the ones for sea0.
Finall", remem%er to add sea1 to "our scenegraph.
0our code should loo+ li+e this-
5. package seaapp;
6.
7. import javafx.application.Application;
8. import javafx.beans.property.DoubleProperty;
9. import javafx.beans.property.SimpleDoubleProperty;
10. import javafx.event.EventHandler;
11. import javafx.scene.Scene;
12. import javafx.scene.image.Image;
13. import javafx.scene.image.ImageView;
14. import javafx.scene.input.MouseEvent;
15. import javafx.scene.layout.Pane;
16. import javafx.scene.shape.Rectangle;
17. import javafx.stage.Stage;
18. import javafx.stage.StageStyle;
19.
20. /**
21. *
22. * @author angie
23. */
24. public class SeaApp extends Application {
25. private ImageView sea0;
26. private Rectangle seaClip0;
27. private ImageView sea1;
28. private Rectangle seaClip1;
29. private ImageView quit;
30. private double sX = 0;
31. private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
32. /**
33. * @param args the command line arguments
34. */
35. public static void main(String[] args) {
36. launch(args);
37. }
38.
39. @Override
40. public void start(Stage primaryStage) {
41. primaryStage.initStyle(StageStyle.TRANSPARENT);
42.
43. sea0 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea0.jpg")));
44. sea1 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea1.jpg")));
45.
46. seaClip0 = new Rectangle(300, 220);
47. seaClip0.setArcHeight(20);
48. seaClip0.setArcWidth(20);
49. seaClip1 = new Rectangle(300, 220);
50. seaClip1.setArcHeight(20);
51. seaClip1.setArcWidth(20);
52.
53. sea0.setClip(seaClip0);
54. sea1.setClip(seaClip1);
55.
56. settingUpDragging();
57. sea0.xProperty().bind(imageXProperty);
58. sea1.xProperty().bind(imageXProperty);
59.
60. setQuitButton();
61.
62. Pane root = new Pane();
63. root.getChildren().addAll(sea0, sea1, quit);
64. Scene scene = new Scene(root, 300, 250);
65. scene.setFill(null);
66. primaryStage.setScene(scene);
67. primaryStage.show();
68. }
69.
70. private void settingUpDragging() {
71. sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
72. public void handle(MouseEvent me) {
73. sX = me.getSceneX() - imageXProperty.getValue();
74. }
75. });
76.
77. sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
78. public void handle(MouseEvent me) {
79. imageXProperty.set(me.getSceneX() - sX);
80. }
81. });
82. sea1.setOnMousePressed(new EventHandler<MouseEvent>() {
83. public void handle(MouseEvent me) {
84. sX = me.getSceneX() - imageXProperty.getValue();
85. }
86. });
87.
88. sea1.setOnMouseDragged(new EventHandler<MouseEvent>() {
89. public void handle(MouseEvent me) {
90. imageXProperty.set(me.getSceneX() - sX);
91. }
92. });
93. }
94.
95. private void setQuitButton() {
96. quit = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/closeIcon.png")));
97. quit.setFitHeight(25);
98. quit.setFitWidth(25);
99. quit.setX(270);
100. quit.setY(10);
101.
102. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
103. public void handle(MouseEvent me) {
104. System.exit(0);
105. }
106. }));
107. }
108. }
Aun the application
1hen "ou run the application "ou should see the new added image sea1. In our case,
what is happening is images are %een added one on top of the other, so we onl" see
the one on top, %ut sea0 still under it. This %ehavior will %e different depending on the
container "ou are using. B=ore a%out containers later on this la%C.
1e are going to use some animations to show and hide sea1, so we can see sea0 that
is sitting underneath. Initiall" we are going to show sea0 %" hiding sea1, and as the
mouse move over it, we are going to show sea1, hiding sea0. For the visi%ilit" of the
image, we can use the imageHs opacit", when itHs ?. the image is visi%le, when itHs set
to . the image is transparent.
First, lets set the opacit" of sea1 to ., ma+ing this image transparent. #dd the
following code after "ou create sea? o%Eect. Bin our case line <:
th
C
45. sea1.setOpacity(0.0);
Implement setOnMouseEntered and setOnMouseExited for sea1. (n mouse
entered we set sea1Hs opacit" to ?., on mouse exit we set sea1Hs opacit" to ..
0ou can add this method at the end of the &ea#pp class
private void setUpVisibility() {
sea1.setOnMouseEntered(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
sea1.setOpacity(1.0);
}
});
sea1.setOnMouseExited(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
sea1.setOpacity(0.0);
}
});
}
#dd setUpVisibility method call after settingUpDragging method call.
In our case line :5
th
.
0our code should loo+ li+e this-
5. package seaapp;
6.
7. import javafx.application.Application;
8. import javafx.beans.property.DoubleProperty;
9. import javafx.beans.property.SimpleDoubleProperty;
10. import javafx.event.EventHandler;
11. import javafx.scene.Scene;
12. import javafx.scene.image.Image;
13. import javafx.scene.image.ImageView;
14. import javafx.scene.input.MouseEvent;
15. import javafx.scene.layout.Pane;
16. import javafx.scene.shape.Rectangle;
17. import javafx.stage.Stage;
18. import javafx.stage.StageStyle;
19.
20. /**
21. *
22. * @author angie
23. */
24. public class SeaApp extends Application {
25. private ImageView sea0;
26. private Rectangle seaClip0;
27. private ImageView sea1;
28. private Rectangle seaClip1;
29. private ImageView quit;
30. private double sX = 0;
31. private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
32. /**
33. * @param args the command line arguments
34. */
35. public static void main(String[] args) {
36. launch(args);
37. }
38.
39. @Override
40. public void start(Stage primaryStage) {
41. primaryStage.initStyle(StageStyle.TRANSPARENT);
42.
43. sea0 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea0.jpg")));
44. sea1 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea1.jpg")));
45. sea1.setOpacity(0.0);
46.
47. seaClip0 = new Rectangle(300, 220);
48. seaClip0.setArcHeight(20);
49. seaClip0.setArcWidth(20);
50. seaClip1 = new Rectangle(300, 220);
51. seaClip1.setArcHeight(20);
52. seaClip1.setArcWidth(20);
53.
54. sea0.setClip(seaClip0);
55. sea1.setClip(seaClip1);
56.
57. settingUpDragging();
58. setUpVisibility();
59.
60. sea0.xProperty().bind(imageXProperty);
61. sea1.xProperty().bind(imageXProperty);
62.
63. setQuitButton();
64.
65. Pane root = new Pane();
66. root.getChildren().addAll(sea0, sea1,quit);
67. Scene scene = new Scene(root, 300, 250);
68. scene.setFill(null);
69. primaryStage.setScene(scene);
70. primaryStage.show();
71. }
72.
73. private void settingUpDragging() {
74. sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
75. public void handle(MouseEvent me) {
76. sX = me.getSceneX() - imageXProperty.getValue();
77. }
78. });
79.
80. sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
81. public void handle(MouseEvent me) {
82. imageXProperty.set(me.getSceneX() - sX);
83. }
84. });
85. sea1.setOnMousePressed(new EventHandler<MouseEvent>() {
86. public void handle(MouseEvent me) {
87. sX = me.getSceneX() - imageXProperty.getValue();
88. }
89. });
90.
91. sea1.setOnMouseDragged(new EventHandler<MouseEvent>() {
92. public void handle(MouseEvent me) {
93. imageXProperty.set(me.getSceneX() - sX);
94. }
95. });
96. }
97.
98. private void setQuitButton() {
99. quit = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/closeIcon.png")));
100. quit.setFitHeight(25);
101. quit.setFitWidth(25);
102. quit.setX(270);
103. quit.setY(10);
104.
105. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
106. public void handle(MouseEvent me) {
107. System.exit(0);
108. }
109. }));
110. }
111.
112. private void setUpVisibility() {
113. sea1.setOnMouseEntered(new EventHandler<MouseEvent>() {
114. public void handle(MouseEvent me) {
115. sea1.setOpacity(1.0);
116. }
117. });
118.
119. sea1.setOnMouseExited(new EventHandler<MouseEvent>() {
120. public void handle(MouseEvent me) {
121. sea1.setOpacity(0.0);
122. }
123. });
124. }
125. }
Aun the program.
0ou can notice that we o%tained the desired result- as "our mouse enter and exit
the applicationHs area, "ou alternate from one image to the other, however it
happens a%ruptl". 1e want to have a nice and smooth transition %etween
images, so lets use animations instead of direct value assignment.
In JavaFX as part of the animation pac+age we have transitions, and one useful
transition is FadeTransition. Fade transition creates a fade effect animation
that spans its duration. This is done %" updating the opacit" varia%le of the node
at regular interval. This is exactl" what we want to do.
For a FadeTransition "ou normall" set the fromValue, or nodeHs opacit" at the
%eginning of the transition, and the toValue, or nodeHs opacit" at the end of the
interval once the transition finish.
First define "our FadeTransition
private FadeTransition fadeTransition;
Fix the imports
Inside the start method we need to create the fadeTransition-
The constructor needs two parameters-
duration J The duration of the FadeTransition, in our case ?ms
node J The node which opacit" will %e animated, in our case sea1
&et the fromValue and the toValue for the animation.
fromValue J . BO invisi%leC
toValue J ?. BO visi%leC
fadeTransition = new FadeTransition(Duration.millis(1000), sea1);
fadeTransition.setFromValue(0.0f);
fadeTransition.setToValue(1.0f);
Fix imports as re*uired
,ow, we need to update mouseEntered and mouseExited handlers.
For our application we would li+e to show and also hide image sea1, so we
want to %e a%le to run the transition forward and also %ac+wards. The good
news is we can use the animationHs rate for this. # positive rate means we
are pla"ing the transition forward, a negative rate means we are pla"ing the
transition %ac+wards.
)ets update the setUpVisibility method.
For setOnMouseEntered we want to replace the line
sea1.setOpacity(1.0);
with
fadeTransition.setRate(1.0);
fadeTransition.play();
First, we ma+e sure we are running the animation forward, and then we
pla" it.
For setOnMouseExited we want to replace the line
sea1.setOpacity(0.0);
with
fadeTransition.setRate(-1.0);
fadeTransition.play();
In here, we set the animation to pla" %ac+ward, and then we pla" it.
0our code should loo+ li+e this-
5. package seaapp;
6.
7. import ...
//code commented out
25.
26. public class SeaApp extends Application {
27. private ImageView sea0;
28. private Rectangle seaClip0;
29. private ImageView sea1;
30. private Rectangle seaClip1;
31. private ImageView quit;
32. private double sX = 0;
33. private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
34. private FadeTransition fadeTransition;
35. /**
36. * @param args the command line arguments
37. */
38. public static void main(String[] args) {
39. launch(args);
40. }
41.
42. @Override
43. public void start(Stage primaryStage) {
44. primaryStage.initStyle(StageStyle.TRANSPARENT);
45.
46. sea0 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea0.jpg")));
47. sea1 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea1.jpg")));
48. sea1.setOpacity(0.0);
49.
50. seaClip0 = new Rectangle(300, 220);
51. seaClip0.setArcHeight(20);
52. seaClip0.setArcWidth(20);
53. seaClip1 = new Rectangle(300, 220);
54. seaClip1.setArcHeight(20);
55. seaClip1.setArcWidth(20);
56.
57. sea0.setClip(seaClip0);
58. sea1.setClip(seaClip1);
59.
60. settingUpDragging();
61. setUpVisibility();
62.
63. sea0.xProperty().bind(imageXProperty);
64. sea1.xProperty().bind(imageXProperty);
65.
66. setQuitButton();
67. fadeTransition = new FadeTransition(Duration.millis(1000), sea1);
68. fadeTransition.setFromValue(0.0f);
69. fadeTransition.setToValue(1.0f);
70.
71. Pane root = new Pane();
72. root.getChildren().addAll(sea0, sea1,quit);
73. Scene scene = new Scene(root, 300, 250);
74. scene.setFill(null);
75. primaryStage.setScene(scene);
76. primaryStage.show();
77. }
78.
79. private void settingUpDragging() {
80. sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
81. public void handle(MouseEvent me) {
82. sX = me.getSceneX() - imageXProperty.getValue();
83. }
84. });
85.
86. sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
87. public void handle(MouseEvent me) {
88. imageXProperty.set(me.getSceneX() - sX);
89. }
90. });
91. sea1.setOnMousePressed(new EventHandler<MouseEvent>() {
92. public void handle(MouseEvent me) {
93. sX = me.getSceneX() - imageXProperty.getValue();
94. }
95. });
96.
97. sea1.setOnMouseDragged(new EventHandler<MouseEvent>() {
98. public void handle(MouseEvent me) {
99. imageXProperty.set(me.getSceneX() - sX);
100. }
101. });
102. }
103.
104. private void setQuitButton() {
105. quit = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/closeIcon.png")));
106. quit.setFitHeight(25);
107. quit.setFitWidth(25);
108. quit.setX(270);
109. quit.setY(10);
110.
111. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
112. public void handle(MouseEvent me) {
113. System.exit(0);
114. }
115. }));
116. }
117.
118. private void setUpVisibility() {
119. sea1.setOnMouseEntered(new EventHandler<MouseEvent>() {
120. public void handle(MouseEvent me) {
121. fadeTransition.setRate(1.0);
122. fadeTransition.play();
123. }
124. });
125.
126. sea1.setOnMouseExited(new EventHandler<MouseEvent>() {
127. public void handle(MouseEvent me) {
128. fadeTransition.setRate(-1.0);
129. fadeTransition.play();
130. }
131. });
132. }
133. }
Aun "our application. 0ou should see a nice and smooth transition %etween
images when the mouse enters and exit the application screen.
)ets add a %it of fun to our application %" adding new components, animations and
effects to our images.
First lets add a shar+ image.
35. private ImageView shark;
6reate the ImageView
50. shark = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/shark.png")));
The shark is a "ellow shar+, and it should %e displa"ed whenever the "ellow sea
Bor sea1 imageC get displa"ed. This is a good opportunit" to use %inding again.
)ets %ind the shark's opacit" with sea1Hs opacit"
67. shark.opacityProperty().bind(sea1.opacityProperty());
&et the scale propert" of the shar+ to .5.
51. shark.setScaleX(0.8);
52. shark.setScaleY(0.8);
#dd "our shar+ to "our scenegraph. Update line 44
th
.
79. root.getChildren().addAll(sea0, sea1, shark, quit);
0our code will loo+ li+e this
5. package seaapp;
6.
7. import . //code commented out
20.
21. /**...*/ //code commented out
25.
26. public class SeaApp extends Application {
27. private ImageView sea0;
28. private Rectangle seaClip0;
29. private ImageView sea1;
30. private Rectangle seaClip1;
31. private ImageView quit;
32. private double sX = 0;
33. private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
34. private FadeTransition fadeTransition;
35. private ImageView shark;
36. /**
37. * @param args the command line arguments
38. */
39. public static void main(String[] args) {
40. launch(args);
41. }
42.
43. @Override
44. public void start(Stage primaryStage) {
45. primaryStage.initStyle(StageStyle.TRANSPARENT);
46.
47. sea0 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea0.jpg")));
48. sea1 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea1.jpg")));
49. sea1.setOpacity(0.0);
50. shark = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/shark.png")));
51. shark.setScaleX(0.8);
52. shark.setScaleY(0.8);
53.
54. seaClip0 = new Rectangle(300, 220);
55. seaClip0.setArcHeight(20);
56. seaClip0.setArcWidth(20);
57. seaClip1 = new Rectangle(300, 220);
58. seaClip1.setArcHeight(20);
59. seaClip1.setArcWidth(20);
60.
61. sea0.setClip(seaClip0);
62. sea1.setClip(seaClip1);
63.
64. settingUpDragging();
65. setUpVisibility();
66.
67. sea0.xProperty().bind(imageXProperty);
68. sea1.xProperty().bind(imageXProperty);
69. shark.opacityProperty().bind(sea1.opacityProperty());
70.
71. setQuitButton();
72. fadeTransition = new FadeTransition(Duration.millis(1000), sea1);
73. fadeTransition.setFromValue(0.0f);
74. fadeTransition.setToValue(1.0f);
75.
76. Pane root = new Pane();
77. root.getChildren().addAll(sea0, sea1, shark, quit);
78. Scene scene = new Scene(root, 300, 250);
79. scene.setFill(null);
80. primaryStage.setScene(scene);
81. primaryStage.show();
82. }
83.
84. private void settingUpDragging() {} //code commented out
108.
109. private void setQuitButton() { } //code commented out
122.
123. private void setUpVisibility() { } //code commented out
138.}
Aun "our application and notice the two shar+s when "ou activate the "ellow sea
%ac+ground.
)ets add some cool effects to the shar+s.
1e can use the DropShadow class to render a shadow for the shar+s with the
specified color, radius, and offset.
First declare the shadow component, and fix imports
36. private DropShadow sharkShadow;
,ow create a %lac+ shadow, set the x and " offsets to :.
54. sharkShadow = new DropShadow();
55. sharkShadow.setColor(Color.BLACK);
56. sharkShadow.setOffsetX(5.0);
57. sharkShadow.setOffsetY(5.0);
&et the shar+Hs effect
58. shark.setEffect(sharkShadow);
Aun the app one more time, and see the difference.
,ote- #t the time this la% was created, there was a %ug and the shadow doesnHt
seems to %e coordinated with the shar+Hs fade animation. The %ug has alread"
%een filled and itHs something we are wor+ing on.
8efore we continue, lets refactor again the code, so it loo+s more organiKed.
&elect all the shar+ code within the start method, and select Aefactor J
Introduce =ethod...
,ame the new method setSharks
0our code should loo+ li+e this:
package seaapp;
import javafx.scene.effect.DropShadow;
import . //code commented out
public class SeaApp extends Application {
private ImageView sea0;
private Rectangle seaClip0;
private ImageView sea1;
private Rectangle seaClip1;
private ImageView quit;
private ImageView shark;
private DropShadow sharkShadow;
private double sX = 0;
private SimpleDoubleProperty imageXProperty = new SimpleDoubleProperty(0);

private FadeTransition fadeTransition;
public static void main(String[] args) {.} //code commented out

@Override
public void start(Stage primaryStage) {.} //code commented out
private void setSharks() {
shark = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/shark.png")));
shark.opacityProperty().bind(sea1.opacityProperty());
shark.setScaleX(0.8);
shark.setScaleY(0.8);

sharkShadow = new DropShadow();
sharkShadow.setColor(Color.BLACK);
sharkShadow.setOffsetX(5.0);
sharkShadow.setOffsetY(5.0);
shark.setEffect(sharkShadow);
}
private void setUpDragging() {.} //code commented out
private void setUpVisibility() {.} //code commented out
private void setQuitButton() {.} //code commented out
}
Finall", lets animate the shar+s, so the" can swim awa". For this animation we are
going to use Timelines. Timeline provides the capa%ilit" to update the propert" values
along the progression of time using a set of KeyFrames.
Timeline specifies how "our application %ehaves over time, for example, we want to
animate a circle, %" modif"ing the radius propert". # KeyFrame defines target values at
a specified point in time, for example at timeO, the radius value Bcalled KeyValueC is
2, and at time O :s, KeyValue will %e 2. 8" default a linear interpolation will %e
performed, unless otherwise itHs specified.
final Circle circle = new Circle(100, 100, 30);

final Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(circle.radiusProperty(), 30)),
new KeyFrame(new Duration(5000),
new KeyValue(circle.radiusProperty(), 300)));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(true);
timeline.play();

The TimelineHs cycleCount will specif" how man" times the animation will %e
performed and the autoReverse, allows "ou to pla" the animation forward and
%ac+ward. 1hen "ou run the previous code, "ou will have a circle that grows till itHs
radius is 2 and the" shrin+ till itHs radius is 2. 3ach c"cle will ta+e : seconds Bor as
specified : millisecondsC
,ow that we have %etter understanding of Timeline, KeyFrame and KeyValue, we can
add some animation for the shar+s. 1e want the shar+s to swim awa"- the" need to
move along the x and " coordinates, and the" need to %e Koomed in to give the
impression of proximit". #nother tric+ we can use, is to move the shadow a %it slower
than the shar+s, this will give us an impression that the shar+s are getting closer to us,
as their shadow is left %ehind.
First we need to create some properties-
private SimpleDoubleProperty xOff = new SimpleDoubleProperty(0.0);
private SimpleDoubleProperty yOff = new SimpleDoubleProperty(0.0);
private SimpleDoubleProperty sOff = new SimpleDoubleProperty(5.0);
private SimpleDoubleProperty scale = new SimpleDoubleProperty(0.8);
xOff and yOff are two properties we are going to use for moving the shar+s
along x and " coordinates. The" will %e %ound to shar+Hs xProperty and
yProperty.
sOff will %e %ound to the shadowHs xProperty and yProperty.
scale will allow us to Koom in the shar+s, and it will %e %ound to
scaleXProperty and scaleYProperty.
)ets define the %inding for the shar+ and shadowHs properties. =a+e sure "ou
update the setSharks methods correctl" to match the following code.
private void setSharks() {
shark = new ImageView(new Image(SeaApp.class.
getResourceAsStream("images/shark.png")));
shark.opacityProperty().bind(sea1.opacityProperty());
shark.scaleXProperty().bind(scale);
shark.scaleYProperty().bind(scale);
shark.xProperty().bind(xOff);
shark.yProperty().bind(yOff);

sharkShadow = new DropShadow();
sharkShadow.setColor(Color.BLACK);
sharkShadow.offsetXProperty().bind(sOff);
sharkShadow.offsetYProperty().bind(sOff);

shark.setEffect(sharkShadow);
}
!eclare the Timeline
private Timeline sharkSwimAway;
6reate sharkSwimAway Timeline
sharkSwimAway = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(sOff, 0),
new KeyValue(scale, 0.8),
new KeyValue(xOff, 0),
new KeyValue(yOff, 0)),
new KeyFrame(new Duration(5000),
new KeyValue(sOff, -100),
new KeyValue(scale, 4.0),
new KeyValue(xOff, 2500),
new KeyValue(yOff, 800))
);
1e are going to trigger the animation when the user clic+ on the shar+s
shark.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
sharkSwimAway.play();
}
});
Update the scene siKe, so the shar+s will have enough space to swim
Scene scene = new Scene(root, 1200, 1000); //use screen resolution
8efore we can run the code, there is one final thing we need to fix. #s the shar+s
are place on top of sea0 and sea1, when the mouse go over them, it will trigger
the mouseExited on sea1, changing the %ac+ground, %ut we havenHt reall" gone
out of the application area. ItHs also the case for mouseEntered, onl" after reall"
exiting the image we should %e a%le to trigger the mouseEntered events. This
can %e easil" fixed-
1hen we detect a mouseExited event we chec+ to see if we reall" got out of
the image, or we simple stood on top of the shar+s.
1e +eep a boolean varia%le that let us +eep trac+ of when we go out of the
screen
Include a new varia%le-
private boolean exited = true;
=a+e sure "ou update the setUpVisibility method as follow.
private void setUpVisibility() {
sea1.setOnMouseEntered(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
if(exited){
fadeTransition.setRate(1.0);
fadeTransition.play();
exited = false;
}
}
});
sea1.setOnMouseExited(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
if (!seaClip1.contains(new Point2D(me.getSceneX(),
me.getSceneY()))){
fadeTransition.setRate(-1.0);
fadeTransition.play();
exited = true;
}
}
});
}
0our final code should loo+ li+e this-
5. package seaapp;
6.
7. import javafx.animation.FadeTransition;
8. import javafx.animation.KeyFrame;
9. import javafx.animation.KeyValue;
10. import javafx.animation.Timeline;
11. import javafx.application.Application;
12. import javafx.beans.property.DoubleProperty;
13. import javafx.beans.property.SimpleDoubleProperty;
14. import javafx.event.EventHandler;
15. import javafx.geometry.Point2D;
16. import javafx.scene.Scene;
17. import javafx.scene.effect.DropShadow;
18. import javafx.scene.image.Image;
19. import javafx.scene.image.ImageView;
20. import javafx.scene.input.MouseEvent;
21. import javafx.scene.layout.Pane;
22. import javafx.scene.paint.Color;
23. import javafx.scene.shape.Rectangle;
24. import javafx.stage.Stage;
25. import javafx.stage.StageStyle;
26. import javafx.util.Duration;
27.
28. /**
29. *
30. * @author angie
31. */
32. public class SeaApp extends Application {
33. private ImageView sea0;
34. private Rectangle seaClip0;
35. private ImageView sea1;
36. private Rectangle seaClip1;
37. private ImageView quit;
38. private double sX = 0;
39. private DoubleProperty imageXProperty = new SimpleDoubleProperty(0);
40. private FadeTransition fadeTransition;
41. private ImageView shark;
42. private DropShadow sharkShadow;
43.
44. private SimpleDoubleProperty xOff = new SimpleDoubleProperty(0.0);
45. private SimpleDoubleProperty yOff = new SimpleDoubleProperty(0.0);
46. private SimpleDoubleProperty sOff = new SimpleDoubleProperty(5.0);
47. private SimpleDoubleProperty scale = new SimpleDoubleProperty(0.8);
48.
49. private boolean exited = true;
50. private Timeline sharkSwimAway;
51. /**
52. * @param args the command line arguments
53. */
54. public static void main(String[] args) {
55. launch(args);
56. }
57.
58. @Override
59. public void start(Stage primaryStage) {
60. primaryStage.initStyle(StageStyle.TRANSPARENT);
61.
62. sea0 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea0.jpg")));
63. sea1 = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/sea1.jpg")));
64. sea1.setOpacity(0.0);
65. setShark();
66.
67. seaClip0 = new Rectangle(300, 220);
68. seaClip0.setArcHeight(20);
69. seaClip0.setArcWidth(20);
70. seaClip1 = new Rectangle(300, 220);
71. seaClip1.setArcHeight(20);
72. seaClip1.setArcWidth(20);
73.
74. sea0.setClip(seaClip0);
75. sea1.setClip(seaClip1);
76.
77. settingUpDragging();
78. setUpVisibility();
79.
80. sea0.xProperty().bind(imageXProperty);
81. sea1.xProperty().bind(imageXProperty);
82.
83.
84. setQuitButton();
85. fadeTransition = new FadeTransition(Duration.millis(1000), sea1);
86. fadeTransition.setFromValue(0.0f);
87. fadeTransition.setToValue(1.0f);
88.
89. Pane root = new Pane();
90. root.getChildren().addAll(sea0, sea1, shark, quit);
91. Scene scene = new Scene(root, 1000, 800);
92. scene.setFill(null);
93. primaryStage.setScene(scene);
94. primaryStage.show();
95. }
96.
97. private void setShark() {
98. shark = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/shark.png")));
99. shark.scaleXProperty().bind(scale);
100. shark.scaleYProperty().bind(scale);
101. shark.xProperty().bind(xOff);
102. shark.yProperty().bind(yOff);
103. sharkShadow = new DropShadow();
104. sharkShadow.setColor(Color.BLACK);
105. sharkShadow.offsetXProperty().bind(sOff);
106. sharkShadow.offsetYProperty().bind(sOff);
107. shark.setEffect(sharkShadow);
108. shark.opacityProperty().bind(sea1.opacityProperty());
109.
110. sharkSwimAway = new Timeline(new KeyFrame(Duration.ZERO,
111. new KeyValue(sOff, 0),
112. new KeyValue(scale, 0.8),
113. new KeyValue(xOff, 0),
114. new KeyValue(yOff, 0)),
115. new KeyFrame(new Duration(5000),
116. new KeyValue(sOff, -100),
117. new KeyValue(scale, 4.0),
118. new KeyValue(xOff, 2500),
119. new KeyValue(yOff, 800)) );
120.
121. shark.setOnMouseClicked(new EventHandler<MouseEvent>() {
122. public void handle(MouseEvent me) {
123. sharkSwimAway.play();
124. } });
125. }
126.
127. private void settingUpDragging() {
128. sea0.setOnMousePressed(new EventHandler<MouseEvent>() {
129. public void handle(MouseEvent me) {
130. sX = me.getSceneX() - imageXProperty.getValue();
131. }
132. });
133.
134. sea0.setOnMouseDragged(new EventHandler<MouseEvent>() {
135. public void handle(MouseEvent me) {
136. imageXProperty.set(me.getSceneX() - sX);
137. }
138. });
139. sea1.setOnMousePressed(new EventHandler<MouseEvent>() {
140. public void handle(MouseEvent me) {
141. sX = me.getSceneX() - imageXProperty.getValue();
142. }
143. });
144.
145. sea1.setOnMouseDragged(new EventHandler<MouseEvent>() {
146. public void handle(MouseEvent me) {
147. imageXProperty.set(me.getSceneX() - sX);
148. }
149. });
150. }
151.
152. private void setQuitButton() {
153. quit = new ImageView(new Image(SeaApp.class.getResourceAsStream
("images/closeIcon.png")));
154. quit.setFitHeight(25);
155. quit.setFitWidth(25);
156. quit.setX(270);
157. quit.setY(10);
158.
159. quit.setOnMouseClicked((new EventHandler<MouseEvent>() {
160. public void handle(MouseEvent me) {
161. System.exit(0);
162. }
163. }));
164. }
165.
166. private void setUpVisibility() {
167. sea1.setOnMouseEntered(new EventHandler<MouseEvent>() {
168. public void handle(MouseEvent me) {
169. if(exited){
170. fadeTransition.setRate(1.0);
171. fadeTransition.play();
172. exited = false;
173. }
174. }
175. });
176.
177. sea1.setOnMouseExited(new EventHandler<MouseEvent>() {
178. public void handle(MouseEvent me) {
179. if (!seaClip1.contains(new Point2D(me.getSceneX(),
180. me.getSceneY()))){
181. fadeTransition.setRate(-1.0);
182. fadeTransition.play();
183. exited = true;
184. }
185. }
186. });
187. }
188. }
Aun the application and verif" that ever"thing is wor+ing as expected.
/0ercise #3 )nderstanding -ayouts "48 mins '
The JavaFX &!/ provides several la"out container classes, called panes, for the eas"
setup and management of classic la"outs such as rows, columns, stac+s, tiles, and
others. #s a window is resiKed, the la"out pane automaticall" repositions and resiKes
the nodes that it contains according to the properties for the nodes. In this exercise we
are going to show "ou how this la"outs wor+s.
8efore we start pla"ing with the different la"outs, lets %ring some resources.
In the previous exercise "ou learned how to add a director" to "our favorites
window, lets add exercise2 director" from our exercises director". BFor more
detailed instructions loo+ into the previous exerciseC
6lic+ on Favorite ta%
Aight clic+ on the %ac+ground and select #dd to Favorites
&elect the director" where "ou unKip the la% file, and go to exercises
&elect exercise2 director" and clic+ on #dd %utton
!order -ayout
6reate a new proEect, called it )a"outs and place it an"where "ou want.
6lic+ on the Favorites ta%
3xpand exercise2D)a"outs director"
&elect the two files- %oats8ig.png and %oats&mall.png
Aight clic+ and select cop" from the pop up menu
6lic+ on the $roEect Ta%
3xpand )a"outs proEect-
3xpand &ource $ac+ages J )a"outs
Aight clic+ on la"outs pac+age and select ,ew J Java $ac+age... from the pop
up menu
The ,ew Java $ac+age window will %e displa"ed
3nter la"outs.images for the pac+age name
6lic+ on Finish
Aight clic+ on the newl" created pac+age and select paste
0our proEect should loo+ li+e the following image
AesiKe the scene to %e :<x:<
Aemove all the lines referring to Button btn Bfrom line 2< P <2C
6omment out the line root.getChildren().add(btn);
,ow lets start pla"ing with 8order$ane )a"out. The BorderPane la"out pane provides
five regions in which to place nodes- top, %ottom, left, right, and center.
#dd the following code in line 22
BorderPane border = new BorderPane();
Fix imports
Uncomment the line with root.getChildren().add(btn);, and replace it with
root.getChildren().add(border);
,ow that "ou create "our container we can start adding components to it
#dd the following code, right after the new %order $ane
border.setTop(new Rectangle(500,100, Color.RED));
border.setBottom(new Rectangle(500,100, Color.RED));
border.setCenter(new ImageView(new Image(Layouts.class.
getResourceAsStream("images/boatsSmall.png"))));
border.setLeft(new Rectangle(100,300, Color.BLUE));
border.setRight(new Rectangle(100,300, Color.BLUE));
Using 8order$ane is extremel" eas", "ou Eust add the components to the area
"ou want, using setTop, setBottom, setCenter, setLeft and setRight
methods.
Aight clic+ on the %ac+ground and select Fix Imports
=a+e sure the Image and Aectangle that "ou select is from the Eavafx li%raries
0our code should loo+ li+e this
5. package layouts;
6.
7. import javafx.application.Application;
8. import javafx.scene.Group;
9. import javafx.scene.Scene;
10. import javafx.scene.image.Image;
11. import javafx.scene.image.ImageView;
12. import javafx.scene.layout.BorderPane;
13. import javafx.scene.paint.Color;
14. import javafx.scene.shape.Rectangle;
15. import javafx.stage.Stage;
16.
17. /**
18. *
19. * @author angie
20. */
21. public class Layouts extends Application {
22.
23. /**
24. * @param args the command line arguments
25. */
26. public static void main(String[] args) {
27. launch(args);
28. }
29.
30. @Override
31. public void start(Stage primaryStage) {
32. primaryStage.setTitle("Border Pane");
33. Group root = new Group();
34. Scene scene = new Scene(root, 540, 540, Color.LIGHTGREEN);
35.
36. BorderPane border = new BorderPane();
37. border.setTop(new Rectangle(500,100, Color.RED));
38. border.setBottom(new Rectangle(500,100, Color.RED));
39. border.setCenter(new ImageView(new Image(Layouts.class.
getResourceAsStream("images/boatsSmall.png"))));
40. border.setLeft(new Rectangle(100,300, Color.BLUE));
41. border.setRight(new Rectangle(100,300, Color.BLUE));
42.
43. root.getChildren().add(border);
44. primaryStage.setScene(scene);
45. primaryStage.show();
46. }
47. }
Aun "our proEect
0ou can also add some padding to "our panel. #dd the following line and run
"our proEect again to see the difference
42. border.setPadding(new Insets(20,20,20,20));
9!o0 and :!o0 Pane
The HBox la"out pane provides an eas" wa" for arranging a series of nodes in a single
row. The VBox la"out pane is similar to the HBox la"out pane, except that the nodes are
arranged in a single column.
$adding attri%utes can %e set to manage the distance %etween the nodes and the edges
of these panes. &pacing attri%utes can %e set to manage the distance %etween the
nodes. The st"le can %e set to change the %ac+ground color.
To do more complex UI, "ou normall" nest different pane. )ets tr" to %uild the following
application-
0ou can notice that it doesnHt fit completel" on a VBox, nor on a HBox, %ut a com%ination
of these panes will %e perfect. The upper part will fit in a HBox, having 2 elements.
Then the HBox with the %igger image at the %ottom will perfectl" fit inside a VBox.
(pen )a"outs2 proEect-
6lic+ on the open proEect icon or use the menu File J (pen $roEect... option.
,avigate to the location where "ou unKipped the la% file
3xtend exercises J exercise2
(pen )a"outs2 proEect
The )a"outs2 proEect alread" has the %asic structure for "ou put "our JavaFX
content, and it has an images director" with the re*uired resources.
=a+e "ou scene 29 x <2 and with a %lac+ %ac+ground.
6reate an Image7iew with the following characteristics
,ame it smallImg
!ispla" imagesD%oats&mall.png image
&iKe 2x4
&et preserveAatio to false
&et smooth to true
Use the Image constructor to set these values
ImageView smallImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png"), 30, 70, false, true));
6reate a second Image7iew-
,ame it smallAotatedImg
!ispla" imagesD%oats&mall.png image
&et the width to <
&et the height to 5
&et preserveAatio to false
&et smooth to true
Aotate the image 9 degree
Use the Image7iewHs methods to set those values
ImageView smallRotatedImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png")));
smallRotatedImg.setFitWidth(40);
smallRotatedImg.setFitHeight(80);
smallRotatedImg.setPreserveRatio(false);
smallRotatedImg.setSmooth(true); //better filter
smallRotatedImg.setRotate(90);
6reate a third ImageView
,ame it viewPortImg
&et the imageHs height to ;
&et preserve ratio to true
ImageView viewPortImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png")));
viewPortImg.setFitHeight(60);
viewPortImg.setPreserveRatio(true);
0ou can set the view port for "our ImageView.
6reate a Rectangle2D for the view port
&et Rectangle2D's x and " to , width to ?2 and height to ;
&et the ImageView's view port
Rectangle2D rectangle2D = new Rectangle2D(0, 0, 120, 60);
viewPortImg.setViewport(rectangle2D); //image's viewport
,ow, create a HBox to place the ImageViews we Eust created.
6reate an HBox
HBox hBox = new HBox();
&et the spacing %etween components in the HBox to 2
hBox.setSpacing(30);
#dd smallImg, smallRotatedImg and viewPortImg to the HBox.
hBox.getChildren().addAll(smallImg, smallRotatedImg, viewPortImg);
#dd "our HBox to the root
root.getChildren().add(hBox);
Fix imports and ma+e sure "ou alwa"s select the classes from the JavaFX
li%raries
Aun "our proEect.
6reate a <
th
ImageView
,ame it bigImage
&et its width to 2:
&et the preserveAatio to true
ImageView bigImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png")));
bigImg.setFitWidth(250); //preferred width
bigImg.setPreserveRatio(true);
6reate a Vbox and add the HBox and bigImg to it.
VBox vb = new VBox(10);
vb.getChildren().addAll(hBox, bigImg);
Update the rootHs childrens to %e vb instead of hBox
root.getChildren().add(vb);
Fix imports
Aun proEect.
,ow, we are onl" missing the space around the Vbox.
#dd the paneHs padding to %e
Top O 2
Aigth O 2
8ottom O 2
)eft O 2
vb.setPadding(new Insets(20,20,20,20));
Fix imports if re*uired
0our code should loo+ li+e this-
5. package layouts2;
6.
7. import javafx.application.Application;
8. import javafx.geometry.Insets;
9. import javafx.geometry.Rectangle2D;
10. import javafx.scene.Group;
11. import javafx.scene.Scene;
12. import javafx.scene.image.Image;
13. import javafx.scene.image.ImageView;
14. import javafx.scene.layout.HBox;
15. import javafx.scene.layout.VBox;
16. import javafx.scene.paint.Color;
17. import javafx.stage.Stage;
18.
19. /**
20. *
21. * @author angie
22. */
23. public class Layouts2 extends Application {
24.
25. /**
26. * @param args the command line arguments
27. */
28. public static void main(String[] args) {
29. launch(args);
30. }
31.
32. @Override
33. public void start(Stage primaryStage) {
34. primaryStage.setTitle("HBox and VBox");
35. Group root = new Group();
36. Scene scene = new Scene(root, 290, 420, Color.BLACK);
37. ImageView smallImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png"), 30, 70, false, true));
38. ImageView smallRotatedImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png")));
39. smallRotatedImg.setFitWidth(40);
40. smallRotatedImg.setFitHeight(80);
41. smallRotatedImg.setPreserveRatio(false);
42. smallRotatedImg.setSmooth(true); //better filter
43. smallRotatedImg.setRotate(90);
44. ImageView viewPortImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png")));
45. viewPortImg.setFitHeight(60);
46. viewPortImg.setPreserveRatio(true);
47. Rectangle2D rectangle2D = new Rectangle2D(0, 0, 120, 60);
48. viewPortImg.setViewport(rectangle2D); //image's viewport
49. HBox hBox = new HBox();
50. hBox.setSpacing(30);
51. hBox.getChildren().addAll(smallImg, smallRotatedImg, viewPortImg);
52. ImageView bigImg = new ImageView(
new Image(Layouts2.class.getResourceAsStream
("images/boatsSmall.png")));
53. bigImg.setFitWidth(250); //preferred width
54. bigImg.setPreserveRatio(true);
55.
56. VBox vb = new VBox(10);
57. vb.getChildren().addAll(hBox, bigImg);
58. vb.setPadding(new Insets(20,20,20,20));
59. root.getChildren().add(vb);
60. primaryStage.setScene(scene);
61. primaryStage.show();
62. }
63. }
Aun "our proEect and ma+e sure it loo+s li+e the following snapshot.
Grid Pane
The >rid$ane la"out pane ena%les "ou to create a flexi%le grid of rows and columns in
which to la" out nodes. ,odes can %e placed in an" cell in the grid and can span cells
as needed. # grid pane is useful for creating forms or an" la"out that is organiKed in
rows and columns. The following image shows a grid pane that contains an icon, title,
su%title, text and a pie chart. >rid lines show the rows, columns, and gaps %etween the
rows and columns.
>ap properties can %e set to manage the spacing %etween the rows and columns. The
padding propert" can %e set to manage the distance %etween the nodes and the edges
of the grid pane.
(pen )a"outs2 proEect-
6lic+ on the open proEect icon or use the menu File J (pen $roEect... option.
,avigate to the location where "ou unKipped the la% file
3xtend exercises J exercise2
(pen )a"outs2 proEect
The )a"outs2 proEect alread" has the %asic structure for "ou put "our JavaFX
content, and it has an images director" with the re*uired resources.
(pen )a"outs2.Eava file %" dou%le clic+ing to it
&et the scene to %e 2:x2 with no filling color.
Scene scene = new Scene(root, 350, 200);
6reate a >rid$ane named grid
GridPane grid = new GridPane();
#s "ou might alread" notice, the columns and the rows have a little gap %etween
them, set this gap to %e ?
grid.setHgap(10);
grid.setVgap(10);
There is also a padding around the grid, set it to %e 2x2x2x2
grid.setPadding(new Insets(20, 20, 20, 20));
,ow that we have the grid lets start creating the UI components and placing them in the
appropriate position in the grid. Ta+e into consideration that the grid num%ers start from
, for the component on first row, first column
6reate and place the &ales text
6reate a Text o%Eect
,ame- categor"
Initial value- L&ales-M
&et the font to %e 8old Tahoma with siKe 2
#dd it to the grid into- first row, second column
Text category = new Text("Sales:");
category.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
grid.add(category, 1, 0);
6reate and place the text L6urrent 0earM
6reate a Text o%Eect-
,ame- chartTitle
Initial value- L6urrent 0earM
&et the font to %e 8old Tahoma with siKe 2
#dd it to the grid into- first row, third column
Text chartTitle = new Text("Current Year");
chartTitle.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
grid.add(chartTitle, 2, 0);
6reate and place the text L>oods and &ervicesM
6reate a Text o%Eect
,ame- chart&u%title
Initial value- L>oods and &ervicesM
$lace the text in the grid
Aow- &econd
6olumn- In this case the text will expand 2 colums Bcolumn 2 and 2C
Text chartSubtitle = new Text("Goods and Services");
grid.add(chartSubtitle, 1, 1, 2, 1);
6reate and place the house image
6reate an ImageView
,ame- image'ouse
File- imagesDhouse.png
&iKe- :x:
$reserveAatio- true
&mooth- true
#dd it to the grid-
First and second row
First column
ImageView imageHouse = new ImageView(
new Image(Layouts3.class.getResourceAsStream
("images/house.png"), 50,50,true, true));
grid.add(imageHouse, 0, 0, 1, 2);
6reate and place the text L>oods 5QM
6reate the Text o%Eect
,ame- goods$ercent
Text value L>oodsRn5QM
From the master image, we can notice that the Text is placed at the %ottom of
the grid cell, set the vertical alignment to %e 8(TT(=
#dd the text to the third row, first column
Text goodsPercent = new Text("Goods\n80%");
GridPane.setValignment(goodsPercent, VPos.BOTTOM);
grid.add(goodsPercent, 0, 2);
6reate and place the pie chart image
6reate an ImageView
,ame- image6hart
File- imagesDpie6hart.png
&iKe- 2x2
$reserveAatio- true
&mooth- true
#dd it to the grid-
Third row
&econd and third column
ImageView imageChart = new ImageView(
new Image(Layouts3.class.getResourceAsStream
("images/pieChart.png"), 200,200,true, true));
grid.add(imageChart, 1, 2, 2, 1);
6reate and place the text L&ervices 2QM
6reate the Text o%Eect
,ame- services$ercent
Text value L&ervicesRn2QM
From the master image, we can notice that the Text is placed at the top of the
grid cell, set the vertical alignment to %e T($
#dd the text to the third row, fourth column
Text servicesPercent = new Text("Services\n20%");
GridPane.setValignment(servicesPercent, VPos.TOP);
grid.add(servicesPercent, 3, 2);
#dd the grid to the root
root.getChildren().add(grid);
5. package layouts3;
6.
7. import javafx.application.Application;
8. import javafx.geometry.Insets;
9. import javafx.geometry.VPos;
10. import javafx.scene.Group;
11. import javafx.scene.Scene;
12. import javafx.scene.image.Image;
13. import javafx.scene.image.ImageView;
14. import javafx.scene.layout.GridPane;
15. import javafx.scene.paint.Color;
16. import javafx.scene.text.Font;
17. import javafx.scene.text.FontWeight;
18. import javafx.scene.text.Text;
19. import javafx.stage.Stage;
20.
21. /**
22. *
23. * @author angie
24. */
25. public class Layouts3 extends Application {
26.
27. /**
28. * @param args the command line arguments
29. */
30. public static void main(String[] args) {
31. launch(args);
32. }
33.
34. @Override
35. public void start(Stage primaryStage) {
36. primaryStage.setTitle("Grid Pane");
37. Group root = new Group();
38. Scene scene = new Scene(root, 350, 200);
39.
40. GridPane grid = new GridPane();
41. grid.setHgap(10);
42. grid.setVgap(10);
43. grid.setPadding(new Insets(20, 20, 20, 20));
44.
45. // Category in column 2, row 1
46. Text category = new Text("Sales:");
47. category.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
48. grid.add(category, 1, 0);
49.
50. // Title in column 3, row 1
51. Text chartTitle = new Text("Current Year");
52. chartTitle.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
53. grid.add(chartTitle, 2, 0);
54.
55. // Subtitle in columns 2-3, row 2
56. Text chartSubtitle = new Text("Goods and Services");
57. grid.add(chartSubtitle, 1, 1, 2, 1);
58.
59. // House icon in column 1, rows 1-2
60. ImageView imageHouse = new ImageView(
new Image(Layouts3.class.getResourceAsStream
("images/house.png"), 50,50,true, true));
61. grid.add(imageHouse, 0, 0, 1, 2);
62.
63. // Left label in column 1 (bottom), row 3
64. Text goodsPercent = new Text("Goods\n80%");
65. GridPane.setValignment(goodsPercent, VPos.BOTTOM);
66. grid.add(goodsPercent, 0, 2);
67.
68. // Chart in columns 2-3, row 3
69. ImageView imageChart = new ImageView(
new Image(Layouts3.class.getResourceAsStream
("images/pieChart.png"), 200,200,true, true));
70. grid.add(imageChart, 1, 2, 2, 1);
71.
72. // Right label in column 4 (top), row 3
73. Text servicesPercent = new Text("Services\n20%");
74. GridPane.setValignment(servicesPercent, VPos.TOP);
75. grid.add(servicesPercent, 3, 2);
76.
77. root.getChildren().add(grid);
78. primaryStage.setScene(scene);
79. primaryStage.show();
80. }
81. }
/0ercise &3 /m.edded !rowser " 40 mins '
JavaFX &!/ introduces the em%edded %rowser, a user interface component that
provides a we% viewer and full %rowsing functionalit" through its #$I. The em%edded
%rowser component is %ased on WebKit, an open source we% %rowser engine. It
supports 'T=):, 6ascading &t"le &heets B6&&C, Java&cript, and the !ocument (%Eect
=odel B!(=C.
WebEngine 6lass
The WebEngine class provides %asic we% page functionalit". It supports user interaction
such as navigating lin+s and su%mitting 'T=) forms. The WebEngine class handles one
we% page at a time. The %asic %rowsing features of loading 'T=) content and
accessing the !(= are availa%le in a %uilt-in we% engine.
WebView 6lass
The WebView class is an extension of the Node class. It encapsulates a WebEngine
o%Eect, incorporates 'T=) content into an applicationHs scene, and provides fields and
methods to appl" effects and transformations. # WebEngine its created when "ou create
a WebView o%Eect. 0ou can alwa"s get the WebEngine using the getEngine method.
In this exercise we are going to create a %rowser li+e the one we show in the following
image
Stes
(pen 8rowser proEect-
6lic+ on the open proEect icon or use the menu File J (pen $roEect... option.
,avigate to the location where "ou unKipped the la% file
3xtend exercises J exercise<
(pen 8rowser proEect
The 8rowser proEect alread" has the %asic structure for "ou put "our JavaFX
content, and it has an images director" with the re*uired resources.
(pen 8rowser.Eava file %" dou%le clic+ing to it
&et the scene to %e :2x: with no filling color.
6reate an HBox for the top %ar
&et some spacing %etween components
&et some padding
&et the components alignment to %e BOTTOM_CENTER
#dd the following nodes to the HBox
LUA)M text
TextField for the UA)
ImageView for the search icon
HBox barContents = new HBox();
barContents.setSpacing(15);
barContents.setPadding(new Insets(15, 15, 15, 15));
barContents.setAlignment(Pos.BOTTOM_CENTER);
Text urlTxt = new Text("URL:");
urlTxt.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
final TextField url = new TextField();
url.setText("http://www.twitter.com");
url.setPrefSize(370, 25);
url.setStyle("-fx-background-color: #336699");

ImageView go = new ImageView(
new Image(Browser.class.getResourceAsStream
("images/search.png")));
barContents.getChildren().addAll(urlTxt, url, go);
6reate a %ac+ground rectangle with a LinearGradient as the top %arHs filling
&et the &tro+e color
&et the arcs for the rectangle
6reate a stac+ pane
#dd the %ac+ground rectangle
#dd the %ar contents BHBoxC
Rectangle barBackground = new Rectangle(500.0, 50.0);
barBackground.setFill(
new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE,
new Stop[]{
new Stop(0, Color.web("#4977A3")),
new Stop(0.5, Color.web("#B0C6DA")),
new Stop(1, Color.web("#9CB6CF")),}));
barBackground.setStroke(Color.web("#D0E6FA"));
barBackground.setArcHeight(3.5);
barBackground.setArcWidth(3.5);
StackPane stack = new StackPane();
stack.setPadding(new Insets(10, 10, 10, 10));
stack.getChildren().addAll(barBackground, barContents);
6reate a 1e%7iew, set la"outs and siKe
>et the 1e%3ngine from the 1e%7iew and load http-DDwww.twitter.com.
private WebEngine myWeb;
...

WebView webView = new WebView();
webView.setLayoutX(10);
webView.setLayoutY(70);
webView.setPrefSize(500, 420);

myWeb = webView.getEngine();
try {
myWeb.load("http://www.twitter.com");
} catch (Exception e) {
System.out.println("Exception while opening the url");
}
&et the set(n=ouse6lic+ed for the go image
>et the value of the url
load the new page in the %rowser
go.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
try {
myWeb.load(url.getText());
} catch (Exception e) {
System.out.println("Exception while opening the url");
}
}
});
Finall" add the stac+ and the we% view into the root
0our code should loo+ li+e this
5. package browser;
6.
7. import javafx.application.Application;
8. import javafx.event.EventHandler;
9. import javafx.geometry.Insets;
10. import javafx.geometry.Pos;
11. import javafx.scene.Group;
12. import javafx.scene.Scene;
13. import javafx.scene.control.TextField;
14. import javafx.scene.image.Image;
15. import javafx.scene.image.ImageView;
16. import javafx.scene.input.MouseEvent;
17. import javafx.scene.layout.HBox;
18. import javafx.scene.layout.StackPane;
19. import javafx.scene.paint.Color;
20. import javafx.scene.paint.CycleMethod;
21. import javafx.scene.paint.LinearGradient;
22. import javafx.scene.paint.Stop;
23. import javafx.scene.shape.Rectangle;
24. import javafx.scene.text.Font;
25. import javafx.scene.text.FontWeight;
26. import javafx.scene.text.Text;
27. import javafx.scene.web.WebEngine;
28. import javafx.scene.web.WebView;
29. import javafx.stage.Stage;
30.
31. /**
32. *
33. * @author angie
34. */
35. public class Browser extends Application {
36. private WebEngine myWeb;
37. /**
38. * @param args the command line arguments
39. */
40. public static void main(String[] args) {
41. launch(args);
42. }
43.
44. @Override
45. public void start(Stage primaryStage) {
46.
47. primaryStage.setTitle("My Own Browser");
48. Group root = new Group();
49. Scene scene = new Scene(root, 520, 500);
50.
51. HBox barContents = new HBox();
52. barContents.setSpacing(15);
53. barContents.setPadding(new Insets(15, 15, 15, 15));
54. barContents.setAlignment(Pos.BOTTOM_CENTER);
55.
56. Text urlTxt = new Text("URL:");
57. urlTxt.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));
58.
59. final TextField url = new TextField();
60. url.setText(http://www.twitter.com);
61. url.setPrefSize(370, 25);
62. url.setStyle("-fx-background-color: #336699");
63.
64. ImageView go = new ImageView(
new Image(Browser.class.getResourceAsStream
("images/search.png")));
65. barContents.getChildren().addAll(urlTxt, url, go);
66.
67. StackPane stack = new StackPane();
68. stack.setPadding(new Insets(10, 10, 10, 10));
69. Rectangle barBackground = new Rectangle(500.0, 50.0);
70. barBackground.setFill(
71. new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE,
72. new Stop[]{
73. new Stop(0, Color.web("#4977A3")),
74. new Stop(0.5, Color.web("#B0C6DA")),
75. new Stop(1, Color.web("#9CB6CF")),}));
76. barBackground.setStroke(Color.web("#D0E6FA"));
77. barBackground.setArcHeight(3.5);
78. barBackground.setArcWidth(3.5);
79.
80. stack.getChildren().addAll(barBackground, barContents);
81.
82. WebView webView = new WebView();
83. webView.setLayoutX(10);
84. webView.setLayoutY(70);
85. webView.setPrefSize(500, 420);
86.
87. myWeb = new WebEngine();
88. try {
89. myWeb.load("http://www.twitter.com");
90. } catch (Exception e) {
91. System.out.println("Exception while opening the url");
92. }
93.
94. go.setOnMouseClicked(new EventHandler<MouseEvent>() {
95. public void handle(MouseEvent me) {
96. try {
97. myWeb.load(url.getText());
98. } catch (Exception e) {
99. System.out.println("Exception while opening the url");
100. }
101. }
102. });
103.
104. root.getChildren().addAll(stack, webView);
105. primaryStage.setScene(scene);
106. primaryStage.show();
107. }
108. }
/0ercise 83 ;edia
"1dvanced e0ercise'
The JavaFX media concept is %ased on the following entities.
=edia P # media resource, containing information a%out the media, such as its
source, resolution, and metadata
=edia$la"er P The +e" component providing the controls for pla"ing media
=edia7iew P # ,ode o%Eect to support animation, translucenc", and effects
3ach element of the media functionalit" is availa%le through the JavaFX #$I.
In this exercise "ou will %e creating the following =edia $la"er, "ou alread" has a lot of
expertise with JavaFX to %uild it on "our own. Ta+e advantage of the JavaFX #$Is
docs if "ou got an" *uestion.
Use the following UA) for "our media file-
Shttp-DDdownload.oracle.comDotndocsDproductsDEavafxDoow2?-2.flvM
&uggested solution
5. package mediaTest;
6.
7. import javafx.application.Application;
8. import javafx.application.Platform;
9. import javafx.beans.InvalidationListener;
10. import javafx.beans.Observable;
11. import javafx.event.ActionEvent;
12. import javafx.event.EventHandler;
13. import javafx.geometry.Insets;
14. import javafx.geometry.Pos;
15. import javafx.scene.Group;
16. import javafx.scene.Scene;
17. import javafx.scene.control.Button;
18. import javafx.scene.control.Slider;
19. import javafx.scene.layout.BorderPane;
20. import javafx.scene.layout.HBox;
21. import javafx.scene.media.Media;
22. import javafx.scene.media.MediaPlayer;
23. import javafx.scene.media.MediaPlayer.Status;
24. import javafx.scene.media.MediaView;
25. import javafx.scene.paint.Color;
26. import javafx.stage.Stage;
27. import javafx.util.Duration;
28.
29. /**
30. *
31. * @author angie
32. */
33. public class MediaTest extends Application {
34.
35. private static final String MEDIA_URL =
36. http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv;
37. private MediaPlayer mediaPlayer;
38. private Slider timeSlider;
39. private Button playButton;
40. private final boolean repeat = false;
41. private boolean stopRequested = false;
42. private boolean atEndOfMedia = false;
43. private Duration duration;
44.
45. /**
46. * @param args the command line arguments
47. */
48. public static void main(String[] args) {
49. launch(args);
50. }
51.
52. @Override
53. public void start(Stage primaryStage) {
54. primaryStage.setTitle("Media Player");
55. Group root = new Group();
56. Scene scene = new Scene(root, 400, 360, Color.DARKGREY);
57.
58. mediaPlayer = new MediaPlayer(new Media(MEDIA_URL));
59. MediaView mediaView = new MediaView();
60. mediaView.setMediaPlayer(mediaPlayer);
61. mediaView.setLayoutX(20);
62. mediaView.setLayoutY(20);
63.
64. setUpMediaPlayerBehavior();
65.
66. BorderPane mainPane = new BorderPane();
67. mainPane.setCenter(mediaView);
68. mainPane.setPadding(new Insets(20,20,20,20));
69.
70. HBox controls = new HBox();
71. controls.setAlignment(Pos.CENTER);
72. controls.setPadding(new Insets(5,5,5,5));
73. controls.setSpacing(15);
74.
75. playButton = new Button(">");
76. playButton.setOnAction(new EventHandler<ActionEvent>() {
77. public void handle(ActionEvent e) {
78. Status status = mediaPlayer.getStatus();
79. if (status == Status.UNKNOWN
80. || status == Status.HALTED) {
81. // don't do anything in these states
82. return;
83. }
84. if (status == Status.PAUSED
85. || status == Status.READY
86. || status == Status.STOPPED) {
87. // rewind the movie if we're sitting at the end
88. if (atEndOfMedia) {
89. mediaPlayer.seek(mediaPlayer.getStartTime());
90. atEndOfMedia = false;
91. }
92. mediaPlayer.play();
93. } else {
94. mediaPlayer.pause();
95. }
96. }
97. });
98.
99. timeSlider = new Slider();
100. timeSlider.setMinWidth(50);
101. timeSlider.setMaxWidth(Double.MAX_VALUE);
102. timeSlider.valueProperty().addListener(new InvalidationListener() {
103. public void invalidated(Observable ov) {
104. if (timeSlider.isValueChanging()) {
105. // multiply duration by percentage calculated by slider position
106. mediaPlayer.seek
107. (duration.multiply(timeSlider.getValue() / 100.0));
108. }
109. }
110. });
111.
112.
113. controls.getChildren().addAll(playButton, timeSlider);
114. mainPane.setBottom(controls);
115. root.getChildren().add(mainPane);
116. primaryStage.setScene(scene);
117. primaryStage.show();
118. }
119.
120. private void setUpMediaPlayerBehavior() {
121. mediaPlayer.currentTimeProperty().
122. addListener(new InvalidationListener() {
123. public void invalidated(Observable ov) {
124. updateValues();
125. }
126. });
127.
128. mediaPlayer.setOnPlaying(new Runnable() {
129. public void run() {
130. if (stopRequested) {
131. mediaPlayer.pause();
132. stopRequested = false;
133. } else {
134. playButton.setText("||");
135. }
136. }
137. });
138.
139. mediaPlayer.setOnPaused(new Runnable() {
140. public void run() {
141. playButton.setText(">");
142. }
143. });
144.
145. mediaPlayer.setOnReady(new Runnable() {
146. public void run() {
147. duration = mediaPlayer.getMedia().getDuration();
148. updateValues();
149. }
150. });
151.
152. mediaPlayer.setCycleCount(repeat ? MediaPlayer.INDEFINITE : 1);
153. mediaPlayer.setOnEndOfMedia(new Runnable() {
154.
155. public void run() {
156. if (!repeat) {
157. playButton.setText(">");
158. stopRequested = true;
159. atEndOfMedia = true;
160. }
161. }
162. });
163. }
164.
165. protected void updateValues() {
166. if (timeSlider != null) {
167. Platform.runLater(new Runnable() {
168. public void run() {
169. Duration currentTime = mediaPlayer.getCurrentTime();
170. timeSlider.setDisable(duration.isUnknown());
171. if (!timeSlider.isDisabled()
172. && duration.greaterThan(Duration.ZERO)
173. && !timeSlider.isValueChanging()) {
174. timeSlider.setValue((currentTime.divide(duration)).
175. toMillis() *100.0);
176. }
177.
178. }
179. });
180. }
181. }
182. }
(ongratu2ations, "ou have successfull" finished "our first JavaFX '()sFFFF

Você também pode gostar