Wire It Up10:00 with Craig Dennis
Let's make sure all of our buttons are doing what they should. Because we used reusable small functions, this is easy as pie.
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 up