Resources11:09 with Craig Dennis
As a project grows, managing external non-Java files becomes something you will want to do. Let's build a Resources Root and move our fxml and new CSS files to that new location.
As JavaFX apps grow, you end up needing a little more structure then what is 0:00 provided with the default JavaFX IntelliJ template. 0:04 We are going to be adding more and more resources, files that are not in Java. 0:09 We're gonna add those to our app. 0:13 So resources include images, sounds, FXML files, 0:15 CSS files and really just about anything else you might need in your app. 0:20 First, let's switch our app to have a place to add resources, 0:26 then I'll show you how to add that CSS file I told you about. 0:29 You might've noticed that when we called the FXML loader.load, 0:33 that we used a method called getResource, chained off of the getClass method. 0:37 Now let's talk a little bit about both of those calls. 0:43 Well, first of all, this getClass method here, 0:45 this allows you to get a handle of the class that created your instance. 0:48 As you might've guessed, this is inherited from java.lang.object, 0:52 so every single object can call that method, 0:56 and it's a handy way to get what class created this instance. 0:58 The next bit, getResource, 1:03 it attempts to find the non-Java file with a specified name. 1:05 It works a lot like a file system. 1:09 It works from the relative directory, so in our example here, it is stating look in 1:11 the current directory, which is source/sample, for the file sample.fxml. 1:15 If it finds the file, 1:21 it returns a URL that most functions expecting resources accept. 1:22 So, like I said, we're gonna need a little better structure here, eventually. 1:26 This is starting to litter our file system. 1:30 Now, one best practice in Java projects is to separate out your non-Java files and 1:32 set a resource route, so let's do that. 1:37 So first what you do is you create a new directory. 1:40 You can call it whatever you want. 1:43 I think it makes the most sense usually to call it resources. 1:44 It doesn't need to be named that. 1:47 You can call it whatever you want. 1:48 But now if we come in here and we choose Mark Directory as > Resources Root, 1:50 what'll happen is it'll see. 1:56 See how it changed the way that the folder looks a little bit here? 1:59 It's got these three little gold coins here sitting on the corner. 2:01 Okay, so now inside of our resources directory, 2:05 let's start cleaning stuff up a little. 2:07 Let's make a separate file for our FXML file. 2:09 So we'll make a new directory for FXML. 2:11 Great, so 2:18 now let's drag our sample.fxml file into the fxml, the resources fxml file. 2:20 Okay, so it's gonna say it's asking if we wanna permanently move it, and 2:27 it's asking if we wanna search for references. 2:30 So let's go ahead and let it do the refactoring for us, and 2:32 then we'll make sure it still works. 2:34 So let's click OK. 2:36 So if it moved it, and it popped it open because I had the file open, 2:36 so it moved it and gave me a new one, and here you see that it did do a refactoring. 2:44 Now, it's true that what happened here is it's saying go to the parent directory 2:48 from where I'm at and then go up another one and then go over to resources. 2:53 That works, let's make it a little bit more clear. 2:56 Because we have the resources route, we can just go ahead and clear this off, 2:58 and that says start at the absolute path of /fxml/sample.fxml. 3:04 We don't need the name because it's the root, and 3:09 then this is the folder that it will look in. 3:11 Okay, so let's save that, and let's run it, make sure that we're still working. 3:14 There's our beautiful app. 3:19 So now we can add a new resource file of type CSS. 3:22 Let's make a folder called CSS. 3:25 And again these folders are not required, the folders or directories are not really 3:27 required to have the same name, but I think it makes sense. 3:31 If somebody was coming to look for CSS, they look in the resources CSS folder. 3:33 So let's go ahead and we'll make a CSS file called sample.css. 3:37 Again, doesn't matter, but we're just following the same, 3:42 we got a sample.fxml, we'll do sample.css. 3:46 Okay, so now over on our root node, we'll do is we'll come in here and 3:50 we will set styleSheets equals and we'll 3:55 do /css/sample, and see how it's finding it cuz it's looking in the resource there. 4:02 So that's great. 4:08 As a Java developer, you might be a bit confused with some of the language in CSS. 4:11 For example, 4:15 CSS uses the term class to refer to a style that you apply to multiple elements. 4:16 Now don't confuse this with Java classes, they're not really the same. 4:21 A CSS class simply lets you assign the same styling to 4:25 any element that you'd like. 4:28 In fact, you can apply more than one CSS class to an element 4:30 to combine styling attributes. 4:34 You can add style classes to nodes as you might imagine by using the style class 4:37 attribute, so let's add one to the text node that we've been using for 4:40 the heading. 4:44 Let's say styleClass, and we'll just call it title so 4:48 it'll be a descriptive name of what the thing is. 4:51 So now if we look in our sample.css class, what we can do here is we can say 4:54 anything that has been labeled with the class title, and that looks like this. 4:59 It uses a dot notation, so you define a selector. 5:04 So we say dot, title. 5:07 Since we are going to try and 5:09 style anything with the class title, we'll use the class selector. 5:11 CSS classes are denoted with a period before their name. 5:15 So basically we can just move our inline style over like so. 5:18 So we'll say .title, and anything in between these curly braces, 5:21 which also looks familiar, but 5:27 don't be confused by that, we'll flip over to our FXML. 5:30 And we'll, let's grab all of these style attributes that we had here before. 5:35 So we'll grab those and we'll get rid of this altogether. 5:40 And the typical style is you put each one of these on their own line like that. 5:50 Awesome, so let's do that. 5:55 Let's save that and see. 5:58 Let's run, make sure everything's working. 5:59 Great, it's still there, and we've removed that style. 6:00 So, there are also default classes that could apply to all elements, for 6:06 instance the root note here has the class root automatically. 6:10 So why don't we wipe out the style tag on the grid pane here and use it in the CSS? 6:14 So I'm gonna go ahead and I'm gonna grab this and cut it, and 6:18 I'm going to get rid of this style here, and I'm gonna move that over to our file. 6:21 So let's put that at the top here, .root. 6:26 And we'll break this down here. 6:36 There is also a class that is applied that is the JavaFX class name. 6:44 For instance if we wanted to, 6:48 we can manipulate all text fields in our app by using the class text-field. 6:49 Note that's the dasherized version of text field, so 6:55 if we did .text., it's got a class of .text-field and 7:00 we will set, we had over here. 7:06 Let's go ahead and we'll set his font differently, fx-font-family. 7:14 Helvetica. 7:22 Okay, so we come up here, and we run that now. 7:26 That's Helvetica there. 7:33 So what we're saying is, 7:35 we're saying everything under here is of Papyrus, except for 7:36 things that are text field, this is being overridden with the Helvetica. 7:41 We'd also previously defined an fx:id on the TextField here, right? 7:44 So, this TextField specifically has a fx:id called firstName. 7:48 So to state that you're referring to an id as a selector, you can use a pound sign. 7:54 So you say pound sign firstName fx. 7:59 Let's set the background color to yellow. 8:06 So this is a good place to show off that the more specific a selector, 8:10 the stronger it is. 8:14 For instance, 8:15 the first name text field has the font family inherited from all fonts. 8:16 That's inherited from all text fields is over in, but finally I'm gonna come down 8:20 here and I'm gonna show you that if we put font-family: Impact, 8:24 we'll show that it has, this is just a font name here. 8:31 Because we've been more specific here, it overrides it. 8:39 So the Impact overrides the Helvetica because it's more specific with the ID. 8:43 So here we see that even though we overrode the default font set from 8:47 the root, which is Papyrus. 8:51 We then set all text fields to be Helvetica, but 8:54 then we specifically set this specific text field to be Impact. 8:57 This is how properties cascade. 9:02 That's the C in the CSS. 9:05 All right, so that's a brief overview of what you can do with an external CSS file. 9:07 Now, all of your future scenes could share this one CSS file, so 9:11 imagine having 30 scenes. 9:16 If you point all of these scenes to this file, you can make one single change in 9:17 the CSS file and update every single scene at once. 9:21 So also note how successfully we separated the structure from the presentation. 9:24 So if you haven't noticed yet, I'm not that great at visual design. 9:29 I mean our sub app looks great. 9:33 I mean, okay, it doesn't, and it's okay, I led you down that path through example. 9:37 Truth be told, I have always been sorta bad at this stuff, and 9:42 by this sorta stuff, I mean art in any form really. 9:46 Now, I'm not saying that I don't appreciate art, I totally do. 9:49 It's just in all my years of development I can think of roughly, no, 9:52 actually zero layouts that I've submitted that actually made it into production, 9:56 and I'm totally okay with that. 10:01 It doesn't hurt my feelings. 10:03 How does that not hurt your feelings you ask. 10:05 Well I guess if I think back to it, 10:08 it goes way back to when I used to create art in kindergarten. 10:10 It's always been a mess. 10:14 My mom tells some great stories about it. 10:16 I should let her tell them sometime. 10:18 Thick skin is an important skill to grow in this field. 10:20 People will review what you create, especially the visual stuff. 10:25 Everyone will have their two cents, and I just want you to know, 10:29 not everyone is good at it, and you honestly don't have to be. 10:33 You do need to understand the beginning concepts, but 10:37 after that it'll be up to you to choose your path. 10:39 Now there are people that aren't good at this sort of design thing, and 10:42 they find their way, and they use the skills that they're good at. 10:46 And if you're lucky, you'll get to work alongside 10:49 some of these amazing people that call themselves designers. 10:52 For the remainder of this course, we're going to be using tools that we've learned 10:55 thus far to build an app that a real life Treehouse designer helped create. 10:59 Her name is Susan, and she's incredibly talented. 11:03 Let's get started right after this break. 11:06
You need to sign up for Treehouse in order to download course files.Sign up