This course will be retired on June 1, 2025.
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 make sure all of our buttons are doing what they should. Because we used reusable small functions, this is easy as pie.
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
One of the benefits of breaking
everything into small,
0:00
reusable methods, just like we've
done throughout this project,
0:03
is that you can very easily group them
together into packages of actions.
0:06
And if something changes in the
requirements, you can easily add, remove,
0:09
and share functionality.
0:14
Like I said, I use the Pomodoro Technique
when I do my work, whether it be coding,
0:16
writing scripts, or researching.
0:21
And there's a couple of apps out there,
but I have yet
0:23
to find one that does exactly what I want.
0:25
Now, I definitely wanna be able
to accept tiny interruptions,
0:28
like especially from my kids, so
I'd like to have the ability to pause and
0:31
I'm not talking a long pause,
just a little bit of time.
0:35
Also, sometimes I like to acknowledge
that I'm ready to take my break.
0:39
Now it's very hard to wrap up
immediately at the ending point.
0:43
At least, that's what I find.
0:46
So I want it to get ready for
the next break, but I wanna start it.
0:48
Let's go take a look at the board
real quick and see how we're doing.
0:52
Let's take a look at this board.
0:57
So this notifying one is
definitely done and then some.
0:59
Good job on that one.
1:02
Let's take a look at what's left.
1:05
So this ticket's left because
it's waiting for the pause.
1:06
We already have the colors changing but
it's waiting for the pause, so
1:10
it doesn't know what state it's in.
1:13
And being able to start your break timer,
we could do that restart.
1:14
But we figure that we should leave
it here because of the Play button.
1:17
Let's pull that over.
1:19
And it should be able to
start the Pomodoro attempt.
1:22
Oh, the first one was the break and
the second was the Pomodoro attempt.
1:25
So basically all blocked by
the playing and pausing ability.
1:28
If someone was looking at this board,
1:32
they might actually think
that we were way behind.
1:34
When you enter into design-based projects,
this build-up happens quite a bit.
1:37
Learning how to slice stories so
that we don't create a traffic jam,
1:42
is something that most product
owners get better at over time.
1:45
Now, I wrote these stories so
I can only blame myself.
1:48
But you don't wanna create
these dependent tickets,
1:51
as you want all of your team
members to be able to work at once.
1:53
So right now, everybody's kinda
waiting for this to happen.
1:56
And we don't need to be,
1:59
we could have written these better,
there's solutions for this problem and
2:00
there out of the scope for this course but
I want you to check the teacher's notes.
2:03
Okay, let's go ahead and
get these play and pause buttons working.
2:06
Alright so let's wire up these buttons and
2:10
remember these buttons are in
these stack panes here.
2:14
If you remember, when we started the first
one that we did where we handled restart.
2:16
We wanna have a method just like that.
2:20
And now, we should follow
the same naming structure.
2:22
That's very important when you're
coming in to something like this.
2:24
You wanna follow and make sure that all
of these, follow the same naming pattern.
2:26
So, we had handleRestart here.
2:29
If somebody was looking for the Play
button, then theyd probably look for
2:32
handle play.
2:34
Let's do that.
2:36
So we'll come up to the play button,
which is this one here.
2:36
Which is currently labelled resume,
and we'll say onAction #handlePlay.
2:41
And again pound means
look in the controller.
2:49
And it is looking in the controller and
it can't find it.
2:51
So let's go ahead and
say create that method.
2:54
And before, which we're using already is
2:59
you can see right here in the
handleRestart we're using a play timer.
3:02
So that's what we want to do.
3:04
We wanna playTimer.
3:05
Okay, so let's think this through a bit.
3:09
When the play button is pressed,
we want it basically to go away and
3:11
be replaced by the pause button.
3:15
Wait a second, actually any time
the application is playing,
3:18
we wanna show the pause button.
3:20
It could have started from the restart,
which is right there, and
3:21
we want that pause button to go away.
3:23
So looks like that playTimer is
a really good place to add the styling.
3:25
Cuz remember those
are inside of a stack pane?
3:29
Let's go ahead, let's take a look
at the CSS class really quick.
3:33
So if we come down here into the
definitions here, you'll see that we have
3:36
anything with a .pause, and that was
the style class we have on the button.
3:41
It's hidden, that's why we're not
seeing it currently on that stack bin,
3:44
otherwise it'd be sitting
right next to it.
3:47
And then we say anytime that
we're in the playing state,
3:50
anything with the pause button should
be visible and then vise versa.
3:54
When we're in the playing state, anything
with the play thing should be hidden.
3:58
Does that make sense?
4:01
And they're stacked on top
of each other so it's good.
4:03
Just kinda replaces itself right there.
4:05
So looks like the only code that we have
to do right now is to add that class.
4:07
Right?
4:13
So in our playTimer, that seems like
a good place to do that because if
4:15
anybody calls this method,
they'll get the right class.
4:18
So do you remember how to do that?
4:23
So on the container, we say getStyleClass.
4:25
That returns a list which is a little
strange, and we're gonna add playing.
4:30
Great.
4:36
Okay and then for the pause button,
we just kinda wanna do the reverse.
4:37
Do you think you can do that?
4:42
Go ahead and try it.
4:43
Why don't you add it to the FXML,
create the method, and
4:44
then in that method remove the class.
4:48
If you don't remember how to remove
the class, check out clear attempt styles.
4:52
Pause me and give it a go.
4:56
Here's how I did it.
4:59
In FXML, I came down to the pause button.
5:02
It chose onAction=, I'm gonna use that
same naming structure, handlePause.
5:05
Great, let's go ahead.
5:13
Give me the opportunity.
5:17
Get rid of all the symbol.
5:19
Let's go over here and
we'll say create method handlePause.
5:21
Awesome.
5:25
In the handle pause event,
5:27
what we wanna do is call pauseTimer, which
is a method that we already had written.
5:28
And if we go to the definition of
pauseTimer, and you come in here,
5:32
what we're gonna say is, let's remove that
container.getStyleClass, remove playing.
5:37
So it's toggling it on and off.
5:46
Awesome.
5:50
What do you think, you think we got it?
5:51
Let's go ahead and try it, let's see.
5:53
Okay so let's click our play button.
5:58
Oh.
6:01
We got an error and it was pretty noisy.
6:03
Java null pointer exception
in play timer at line 91.
6:05
If I click this,
it will actually jump there.
6:11
Oh, it's a null pointer on the timeline,
because we didn't initialize the timeline.
6:13
We are in a state where
the timeline hasn't started.
6:20
So let's go ahead.
6:23
Let's make sure that our play and
pause is working.
6:24
Let's click Restart, and
I'm gonna click the Pause button.
6:25
Awesome.
6:29
So it's stopped.
6:30
We are paused, that timeline is paused.
6:32
And, if we click play it will finish.
6:35
There we go.
6:36
Uh-oh, I see another bug.
6:39
Do you see it?
6:41
The pause button is on,
but it's not playing.
6:43
Hmm, you know what let's put that
in the clear attempt styles.
6:46
We already have a thing that's clearing up
all the styles that we've built already.
6:51
Where is that at?
6:55
Here it is, clearAttemptStyles.
6:58
So in here,
why don't we just also remove that.
7:00
Remove playing.
7:02
Awesome.
7:04
So now I'm going to make sure
that I close all of these.
7:05
Remember you can right click and
choose close all.
7:13
I'm going to disconnect,
disconnect, disconnect.
7:15
This happens quite a bit
when you're debugging.
7:17
We'll kick it off.
7:19
All right.
So now let's try from the start.
7:23
Oh right.
7:26
We didn't fix that.
7:27
It just does not work automatically.
7:28
Let's fix that really quick.
7:30
So let's think through.
7:32
What do we need to do to make this work?
7:33
So if there's not an attempt running
we might as well just restart it, and
7:36
restart prepares the attempt.
7:41
And that's basically what we're saying.
7:42
We're saying just start everything over.
7:44
So we'll say if there's
not a CurrentAttempt,
7:46
if the CurrentAttempt is null.
7:48
Let's just go ahead and we'll call
handleRestart, it's the same thing,
7:52
and we'll pass in the actionEvent that
was passed in from this method here.
7:57
Otherwise, let's go ahead and
we'll call playTimer.
8:02
Cool, that looks good.
8:06
Let's make sure.
8:06
So we'll click play.
8:10
Boom, it started.
8:11
It did the restart.
8:12
Awesome.
And now see it's back to being play and
8:14
we can press the play button again and
we can pause it and it holds out for us.
8:17
Awesome.
Now let's go and
8:21
let's remove the last
debugging bits that we have.
8:23
We go over to our FXML.
8:29
Let's get rid of that debug
button that we added earlier and
8:30
let's not forget to get the focus time.
8:34
You don't get to have that many breaks.
8:36
You don't get to work for three seconds
and then get a five minute break.
8:38
That'd be nice.
8:40
25 times 60 is what we want there.
8:42
Let's go back to the board.
8:48
Starting works, the break timer works.
8:51
And we know focus break and
now we know paused.
8:55
We did it.
8:58
Speaking of well deserved breaks
>> [LAUGH]
9:00
>> You deserve one.
9:01
You did it.
9:02
>> [APPLAUSE]
>> Another awesome job.
9:03
Virtual high fives all around.
9:04
This type of programming, breaking things
down into small, describable tasks,
9:08
is in my opinion the key to make
quickly modifiable UI code.
9:13
You wanna be able to change the design and
keep the functionality.
9:18
Oh, and speaking of functionality, I
wanted to show you something really quick.
9:22
But first, I want you to remember that you
got all the way here without using it.
9:27
There are tools that some people believe
are a requirement to making a UI code,
9:32
and that is itself a GUI
interface to making GUIs.
9:37
The one for
Java FX is called Scene Builder.
9:42
You can set up layouts and set attributes
and properties and it handles CSS.
9:45
When you save it, it modifies your FXML.
9:50
It's pretty handy when
you're exploring around and
9:54
it does a pretty good job
of keeping things clean.
9:56
Check the teacher's notes for more info.
9:59
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