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
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.
Learn more
- Learn CSS Selectors here on Treehouse!
- getClass
- getResource
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
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 upYou need to sign up for Treehouse in order to set up Workspace
Sign up