This course will be retired on July 14, 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
Video Player
00:00
00:00
00:00
- 2x 2x
- 1.75x 1.75x
- 1.5x 1.5x
- 1.25x 1.25x
- 1.1x 1.1x
- 1x 1x
- 0.75x 0.75x
- 0.5x 0.5x
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