Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's take a look at another for binding directly from the fxml file. JavaFX exposes a property pattern that handles all the event firing that you will need for two way binding.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
We've seen how to dynamically change
specific nodes using the FXML annotation
0:00
and by defining matching IDs.
0:05
There is a slightly more
powerful way to do things.
0:07
And that is to have your FXML bind,
or watch for changes and
0:09
react, to a specific
property on a controller.
0:13
There are a couple benefits
to doing things this way.
0:17
First, it decouples, or
0:20
removes the dependencies between
the structure and the model.
0:22
Secondly, by using a property,
0:27
additional users can subscribe to its
changes, and do with it what they may.
0:29
It's a little different way of
looking at things than we have been.
0:35
Now usually you wouldn't see the two
different styles colliding, but
0:39
I did want to expose you to this
style of controller usage, so
0:43
you can make the call for yourself.
0:47
You will encounter both styles in JavaFX
code and samples, so it's good for
0:49
you to get acquainted.
0:53
Ready?
0:54
Let's get binding.
0:55
So you know how we've been following
that pattern of making public getter and
0:57
setter methods?
1:00
You know, the ones that start with get and
start with set.
1:01
Well that pattern allows for
external tools to hook into our objects.
1:05
It knows that we expose things
we want to have it get and
1:09
things that we want to have it set.
1:12
Now this pattern of getters and
setters is known as the Java Bean pattern.
1:14
Now you've been using it, but
maybe you didn't realize it.
1:19
Now JavaFx has an additional
bit to add to this pattern.
1:21
It wants you to expose a getter, a setter
and a special JavaFx property object.
1:25
So, let's make one and
then I'll explain it.
1:32
All right, so we want to have
the text of our timer change, so
1:36
let's make one of those properties.
1:39
So they're called private and
we're going to make a StringProperty.
1:41
mTimerText.
1:49
Okay and it's a javafx.beans property.
1:53
And inside of our constructor,
which we don't have on this class,
1:59
let's go ahead and make a new constructor.
2:03
And we'll just make a default constructor,
right.
2:08
That will be called,
automatically already.
2:10
So we'll just make a new one.
2:12
And the implementation that we'll choose
is called simple string properties.
2:13
So mTimerText = new SimpleStringProperty.
2:20
Okay, so let's add our getter and
setter methods for the string property.
2:28
Now IntelliJ is pretty clever about it.
2:32
It knows that there's
a JavaFX Bean style method.
2:33
So let's go ahead and do that.
2:36
Let's do that right below
the constructor here.
2:38
We'll do, we'll construct a getter and
setter for the string property mTimerText.
2:42
Okay.
2:50
And you'll see that it
created getTimerText, and
2:51
it's calling mTimerText.get
when you call it.
2:54
Instead of just returning the mTimerText.
2:56
It's a little bit different than
what we've been seeing before
2:59
with getters and setters.
3:01
And then it also exposes this
timerText suffixed with Property.
3:03
That's the new part that is required
from the JavaFX Bean pattern.
3:07
And then of course there's a set.
3:13
And you'll see too,
instead of just setting mTimerText,
3:14
it's calling mTimerText and
it's calling set on it.
3:17
Okay, so notice how in the controller,
that there's no FXML field for time.
3:21
Let's pop over to the FXML.
3:26
Go resources > FXML > home.fxml.
3:30
And we'll look at the time here.
3:33
And I'm gonna get rid of
the default that's set here.
3:35
What we're gonna do is we are going to
bind to that controller's property.
3:40
And the way that you do that
is you use the dollar sign and
3:44
then you use the mustaches or
curly braces.
3:48
And then you say controller.timerText.
3:52
And you'll see here on my screen, that
there's a bug, or it's reporting a bug.
3:59
IntelliJ shows the controller in error,
but it actually works, and
4:03
there's bugs filed about it.
4:06
Maybe they'll fix it here shortly.
4:07
So what happens now is that
the text property on the label
4:09
is bound to the timerText
property on the controller.
4:13
If we change the value of the timerText
property, it will send a change event.
4:17
This event will then be captured by the
label and update the text appropriately.
4:22
Pretty slick, right?
4:26
This is data binding at work.
4:27
Check the teacher's notes for
more on this.
4:29
So let's test it out, right?
4:31
So let's flip back over to the constructor
and let's call that set timerText Method.
4:33
So well call setTimerText.
4:40
And it's looking for a string.
4:42
So let's just put
something random in there.
4:44
Let's put the word Hammer in there.
4:45
Okay?
4:47
And if we run it.
4:49
Look.
Stop.
4:54
Hammer time!
4:55
And remember over in our
controller over here
4:57
there is no reference at all to that time.
5:01
So it's just by setting this.
5:04
So this is a good way for
5:06
the home.fxml to say to the controller,
you can't touch this.
5:08
Yes, that was a very rare
MC Hammer joke double header,
5:14
and yes, they were both very dumb.
5:16
Okay.
5:19
So we wanna set that text to be the time
remaining and have it tick down.
5:20
Now currently,
our format is an integer though, right?
5:25
I wish there was some way that we could
have a method with the same name but
5:28
worked with different parameters.
5:32
Wait, this is Java, we can.
5:34
Method overloading allows for
different signatures, but the same name.
5:36
So let's make a method that takes
our remaining seconds as an integer,
5:40
and then creates a nice looking format.
5:43
So let's go right underneath the set timer
text, and see that one takes a string.
5:47
Let's pick one that takes an integer.
5:51
Then we'll say remainingSeconds.
5:59
Okay, so all we gotta do is
a little bit of math, right?
6:03
So first let's determine
what the minutes are.
6:07
That's pretty easy, right?
6:09
Remember the way you do that is
we have remainingSeconds, and
6:11
that's divided by 60,
that'll get us the minutes.
6:16
Remember in math those things
called remainders after division happens,
6:19
you know, like, 12 divided by 7 is 1,
and there's a remainder of 5.
6:23
Well, you can do that, and what that's
known as in programming is a modulo.
6:26
So you use the percent sign to do that.
6:32
So let's go ahead and do that.
6:34
So we say, int seconds =
6:35
remainingSeconds % 60.
6:39
So if you divide this by 60,
what's remaining afterwards,
6:44
is what that's saying.
6:47
And then we'll say setTimerText,
again calling the original method,
6:51
and we'll use a String.format and we wanna
make sure that there are leading zeroes.
6:57
And the way that we do that
is you say 0 and at least 2.
7:04
And then you say decimal,
right, so that's the %d.
7:08
But if you put 02 in there,
it will pad it 2 with zeros.
7:12
And then let's do that again, %02d.
7:16
And what will happen there is we can
replace those with minutes, seconds.
7:21
Right, makes sense?
7:30
So, now we can call in
our prepare attempt,
7:32
we can call setTimerText =
mCurrentAttempt.getRemainingSeconds.
7:38
And if we start this off, we can remove
the very dumb joke where we had a hammer,
7:51
and let's just put 0 in there.
7:56
And then let's see what
happens when we run it.
7:58
Perfect.
So there's 0 turned into pretty string,
8:02
00:00.
8:05
Awesome.
8:06
So now you know how to create
properties that when changed
8:08
send events out to all their listeners.
8:12
You also learned how to bind
a property in FXML to a controller.
8:14
This is a really nice powerful pattern
that JavaFX gives you out of the box.
8:19
I've added links in the teacher's notes,
and I highly suggest that you get more
8:24
familiar with this powerful
feature of your GUI framework.
8:28
Nice refresher on method overloading.
8:32
See how practical its use was there?
8:34
We allow anyone to pass in a string or
an integer and
8:36
the timer text gets set properly.
8:40
Remember to use that method overloading
trick to help make what you offer
8:43
very clear to consumers of your code.
8:47
You also learned about
the modulo operator,
8:50
which is used to find the remainder
of division between two numbers.
8:52
For the remainder of this course,
8:56
we're going to get this timer ticking,
right after this exercise.
8:58
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up