MaterialFX is an open source Java library which provides material design components for JavaFX
Explore the wiki »
Download Latest Demo
·
Report Bug
·
Request Feature
Please, before using this library and submitting an issue complaining that controls are not styled and bugged check how the styling system has changed since version 11.14.0
JavaFX is a software platform intended to replace Swing in creating and delivering rich client applications that operate consistently across diverse platforms. With the release of JDK 11 in 2018, Oracle has made JavaFX part of the OpenJDK under the OpenJFX project in order to increase the pace of its development.
Key features:
Over the years the way of creating GUIs has often changed and JavaFX default appearance is still pretty much the same. That's where this project comes in. The aim of my project is to bring components which follow as much as possible the Google's material design guidelines to JavaFX. The second purpose is to provide a successor to the already available JFoenix library, which is a bit old and has a lot of issues.
In recent months the project has evolved a lot, to the point that it is no longer a simple substitute.
To date MaterialFX offers not only restyled controls, but also: new and unique controls such as the Stepper,
controls completely redone from scratch such as ComboBoxes or TableViews (and many others),
and many utilities for JavaFX and Java (NodeUtils, ColorUtils, StringUtils ...).
MaterialFX v11.13.0 brought a lot of fixes and new features, but it also brought a new logo, something that is more
meaningful for me and that somewhat represents the new version.
The new logo is a Phoenix, the immortal bird from Greek mythology, associated to regeneration/rebirth.
When a Phoenix dies it obtains new life by raising from its ashes.
MaterialFX v11.13.0 fixed many critical bugs and broken features, I like to think that it is reborn from
the previous version, so I thought a new logo would have been a good idea.
In this section you can learn what do you need to use my library in your project or see a preview/demo which I'm planning to release as runtime images here on github.
To build MaterialFX, execute the following command:
gradlew build
To run the main demo, execute the following command:
gradlew run
NOTE: MaterialFX requires Java 11 and above.
repositories {
mavenCentral()
}
dependencies {
implementation 'io.github.palexdev:materialfx:11.17.0'
}
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.17.0</version>
</dependency>
You can read MaterialFX's documentation at javadoc.io
See the CHANGELOG file for a list of changes per version.
See the Open Issues for a list of proposed features (and known issues)
.
See the ROADMAP for a list of implemented and upcoming
features.
Since MaterialFX 11.14.0 the way controls are styles through CSS has drastically changed. Before telling you about the new Theming System, and about its pros and cons, let's talk a bit on the history of this project, the causes that brought to this drastic change.
When I started developing MaterialFX I was a complete noob, I knew nothing about JavaFX. But I really wanted to use it
and to make it look good. Competitors had broken libraries that made usage difficult for the end user, I didn't like
them at all.
And so the journey begun, MaterialFX is born. Like any newbies, what do you do when you know nothing but want to
learn?
You check others work and try to copy them but still make the changes you want to implement.
This lead me to create controls that made use of the infamous getUserAgentStylesheet() method. For those of you that
do not know about it, a developer of custom controls is supposed to override that method to provide a CSS stylesheet to
define the author's intended style for the custom control.
Sounds great right, just the thing I need... Well, I'd say that if only it worked properly. This system has been the
root cause of CSS issues right from the start of the project, with little I could do to fix it properly.
(Little secret that almost no one know: I actually sent a PR on the JavaFX repo to improve the system and make it
dynamic, guess what, it's still there lol)
The two most annoying issues caused by this system are:
getUserAgentStylesheet() method of each
children node to use the one of the parent, and even this drastic solution was working half the time (didn't work in
some user cases)End of the rant
How can I fix it? I asked myself many many times.
Recently I've been working on a rewrite of MaterialFX, this new
version will have controls based on the new Material Design 3 Guidelines, will implement modular themes thanks to the
usage of SASS and a Theming API that will let user change themes, implement new ones, very easily.
So the idea is to backport at least the concept on the main branch at least until the rewrite is done.
The Theme API
Themes: this enumerator defines the default themes of MaterialFX, there is the DEFAULT theme that includes the
stylesheets
of all MaterialFX controls, as well as dialogs, popups, menus, etc...Stylesheets: this enumerator defines all the stylesheets of every single control, allowing the user to not use a
theme
(for whatever reason) and instead choose which component he wants to styleMFXThemeManager is a utility class that will help the user add/set themes and stylesheets (which implement Theme) on
nodes or scenes.
Pros
getUserAgentStylesheet()
anymore anywhereCons
public class App extends Application {
@Override
public void start(Stage stage) {
...
Scene scene = ...;
MFXThemeManager.addOn(scene, Themes.DEFAULT, Themes.LEGACY);
}
}
getStylesheets() list it's easy to remove them and define your ownAn interface called Theme, allows users to define custom theme entries. It specifies the bare minimum properties a
theme must have: its path and a way to load it. There are two implementations of this interface:
JavaFXThemes: this enumerator defines the JavaFX's default themes. Since JavaFX 8 the default one is MODENA.
The funny thing about all this crap is that, JavaFX's User-Agents are actually split in multiple CSS files, there is a
main file and then others that are added according to certain system's properties the app is running on. So, they are allowed
to use multiple files, but we are not....thanks for nothing I guess.MaterialFXStylesheets: this enumerator defines all the stylesheets for each MaterialFX control.
However, to make things work as intended, all of them have been merged into a single CSS file called DefaultTheme.css.
The same thing has been done for legacy controls too, the aio CSS file is called LegacyControls.cssNow, the missing core part. The class responsible for building a single User-Agent stylesheet is: UserAgentBuilder.
There are three main aspects of the system you should know, and I'm going to explain them after giving you a short code
example:
UserAgentBuilder.builder()
.themes(JavaFXThemes.MODENA) // Optional if you don't need JavaFX's default theme, still recommended though
.themes(MaterialFXStylesheets.forAssemble(true)) // Adds the MaterialFX's default theme. The boolean argument is to include legacy controls
.setDeploy(true) // Whether to deploy each theme's assets on a temporary dir on the disk
.setResolveAssets(true) // Whether to try resolving @import statements and resources urls
.build() // Assembles all the added themes into a single CSSFragment (very powerful class check its documentation)
.setGlobal(); // Finally, sets the produced stylesheet as the global User-Agent stylesheet
themes(...) method..zip file, and you should be very careful
at the structure inside it. When extracting the files the structure will be honored.@import ../fonts/Font.css.
You know how the API works and packed the font into a zip file, the structure is as follows fonts/Font.css.
The file is going to be extracted in a directory on the disk, let's say osTempDir/myassets/fonts/Font.css.
(You can change the root dir's name by overriding the Theme's deployName() method)
Now, as you may guess, that import statement needs to be changed so that it points to the resource on the disk.
This is exactly what setResolveAssets(true) attempts to do. The result will be something like this:
@import osTempDir/myassets/fonts/Font.cssPros
Cons
UserAgentBuilder to create the theme and set it as the application User-Agent (you can check the code snippet
above to see how to do it).Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the GNU LGPLv3 License. See LICENSE for more information.
Alex - [email protected]
Discussions
Project Link: https://github.com/palexdev/MaterialFX
It's been more than a year since I started developing MaterialFX. Implementing cool looking, fully functional controls,
introducing new components and features as well as providing many utilities for JavaFX and Java is really hard,
especially considering that developing for JavaFX also means to deal with its closeness, its bugs, its annoying
design decisions. Many times I've honestly been on the verge of giving up because sometimes it's really too much
stress to handle.
But, today MaterialFX is a great library, supported by many people and I'm proud of it.
If you are using MaterialFX in your projects and feel like it, I recently
activated GitHub Sponsors so
you can easily donate/sponsor.
(If you want your github page to be linked here and you didn't specify your username in the donation, feel free to contact me by email and tell me. Also contact me if for some some reason you don't want to be listed here)
Thank you very very much to all supporters, to all people who contribute to the project, to all people that thanked me, you really made my day
275 followers · starred May 2021
185 followers · starred Dec 2021
201 followers · starred May 2021
56 followers · starred May 2024
MaterialFX is an open source Java library which provides material design components for JavaFX
Explore the wiki »
Download Latest Demo
·
Report Bug
·
Request Feature
Please, before using this library and submitting an issue complaining that controls are not styled and bugged check how the styling system has changed since version 11.14.0
JavaFX is a software platform intended to replace Swing in creating and delivering rich client applications that operate consistently across diverse platforms. With the release of JDK 11 in 2018, Oracle has made JavaFX part of the OpenJDK under the OpenJFX project in order to increase the pace of its development.
Key features:
Over the years the way of creating GUIs has often changed and JavaFX default appearance is still pretty much the same. That's where this project comes in. The aim of my project is to bring components which follow as much as possible the Google's material design guidelines to JavaFX. The second purpose is to provide a successor to the already available JFoenix library, which is a bit old and has a lot of issues.
In recent months the project has evolved a lot, to the point that it is no longer a simple substitute.
To date MaterialFX offers not only restyled controls, but also: new and unique controls such as the Stepper,
controls completely redone from scratch such as ComboBoxes or TableViews (and many others),
and many utilities for JavaFX and Java (NodeUtils, ColorUtils, StringUtils ...).
MaterialFX v11.13.0 brought a lot of fixes and new features, but it also brought a new logo, something that is more
meaningful for me and that somewhat represents the new version.
The new logo is a Phoenix, the immortal bird from Greek mythology, associated to regeneration/rebirth.
When a Phoenix dies it obtains new life by raising from its ashes.
MaterialFX v11.13.0 fixed many critical bugs and broken features, I like to think that it is reborn from
the previous version, so I thought a new logo would have been a good idea.
In this section you can learn what do you need to use my library in your project or see a preview/demo which I'm planning to release as runtime images here on github.
To build MaterialFX, execute the following command:
gradlew build
To run the main demo, execute the following command:
gradlew run
NOTE: MaterialFX requires Java 11 and above.
repositories {
mavenCentral()
}
dependencies {
implementation 'io.github.palexdev:materialfx:11.17.0'
}
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.17.0</version>
</dependency>
You can read MaterialFX's documentation at javadoc.io
See the CHANGELOG file for a list of changes per version.
See the Open Issues for a list of proposed features (and known issues)
.
See the ROADMAP for a list of implemented and upcoming
features.
Since MaterialFX 11.14.0 the way controls are styles through CSS has drastically changed. Before telling you about the new Theming System, and about its pros and cons, let's talk a bit on the history of this project, the causes that brought to this drastic change.
When I started developing MaterialFX I was a complete noob, I knew nothing about JavaFX. But I really wanted to use it
and to make it look good. Competitors had broken libraries that made usage difficult for the end user, I didn't like
them at all.
And so the journey begun, MaterialFX is born. Like any newbies, what do you do when you know nothing but want to
learn?
You check others work and try to copy them but still make the changes you want to implement.
This lead me to create controls that made use of the infamous getUserAgentStylesheet() method. For those of you that
do not know about it, a developer of custom controls is supposed to override that method to provide a CSS stylesheet to
define the author's intended style for the custom control.
Sounds great right, just the thing I need... Well, I'd say that if only it worked properly. This system has been the
root cause of CSS issues right from the start of the project, with little I could do to fix it properly.
(Little secret that almost no one know: I actually sent a PR on the JavaFX repo to improve the system and make it
dynamic, guess what, it's still there lol)
The two most annoying issues caused by this system are:
getUserAgentStylesheet() method of each
children node to use the one of the parent, and even this drastic solution was working half the time (didn't work in
some user cases)End of the rant
How can I fix it? I asked myself many many times.
Recently I've been working on a rewrite of MaterialFX, this new
version will have controls based on the new Material Design 3 Guidelines, will implement modular themes thanks to the
usage of SASS and a Theming API that will let user change themes, implement new ones, very easily.
So the idea is to backport at least the concept on the main branch at least until the rewrite is done.
The Theme API
Themes: this enumerator defines the default themes of MaterialFX, there is the DEFAULT theme that includes the
stylesheets
of all MaterialFX controls, as well as dialogs, popups, menus, etc...Stylesheets: this enumerator defines all the stylesheets of every single control, allowing the user to not use a
theme
(for whatever reason) and instead choose which component he wants to styleMFXThemeManager is a utility class that will help the user add/set themes and stylesheets (which implement Theme) on
nodes or scenes.
Pros
getUserAgentStylesheet()
anymore anywhereCons
public class App extends Application {
@Override
public void start(Stage stage) {
...
Scene scene = ...;
MFXThemeManager.addOn(scene, Themes.DEFAULT, Themes.LEGACY);
}
}
getStylesheets() list it's easy to remove them and define your ownAn interface called Theme, allows users to define custom theme entries. It specifies the bare minimum properties a
theme must have: its path and a way to load it. There are two implementations of this interface:
JavaFXThemes: this enumerator defines the JavaFX's default themes. Since JavaFX 8 the default one is MODENA.
The funny thing about all this crap is that, JavaFX's User-Agents are actually split in multiple CSS files, there is a
main file and then others that are added according to certain system's properties the app is running on. So, they are allowed
to use multiple files, but we are not....thanks for nothing I guess.MaterialFXStylesheets: this enumerator defines all the stylesheets for each MaterialFX control.
However, to make things work as intended, all of them have been merged into a single CSS file called DefaultTheme.css.
The same thing has been done for legacy controls too, the aio CSS file is called LegacyControls.cssNow, the missing core part. The class responsible for building a single User-Agent stylesheet is: UserAgentBuilder.
There are three main aspects of the system you should know, and I'm going to explain them after giving you a short code
example:
UserAgentBuilder.builder()
.themes(JavaFXThemes.MODENA) // Optional if you don't need JavaFX's default theme, still recommended though
.themes(MaterialFXStylesheets.forAssemble(true)) // Adds the MaterialFX's default theme. The boolean argument is to include legacy controls
.setDeploy(true) // Whether to deploy each theme's assets on a temporary dir on the disk
.setResolveAssets(true) // Whether to try resolving @import statements and resources urls
.build() // Assembles all the added themes into a single CSSFragment (very powerful class check its documentation)
.setGlobal(); // Finally, sets the produced stylesheet as the global User-Agent stylesheet
themes(...) method..zip file, and you should be very careful
at the structure inside it. When extracting the files the structure will be honored.@import ../fonts/Font.css.
You know how the API works and packed the font into a zip file, the structure is as follows fonts/Font.css.
The file is going to be extracted in a directory on the disk, let's say osTempDir/myassets/fonts/Font.css.
(You can change the root dir's name by overriding the Theme's deployName() method)
Now, as you may guess, that import statement needs to be changed so that it points to the resource on the disk.
This is exactly what setResolveAssets(true) attempts to do. The result will be something like this:
@import osTempDir/myassets/fonts/Font.cssPros
Cons
UserAgentBuilder to create the theme and set it as the application User-Agent (you can check the code snippet
above to see how to do it).Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the GNU LGPLv3 License. See LICENSE for more information.
Alex - [email protected]
Discussions
Project Link: https://github.com/palexdev/MaterialFX
It's been more than a year since I started developing MaterialFX. Implementing cool looking, fully functional controls,
introducing new components and features as well as providing many utilities for JavaFX and Java is really hard,
especially considering that developing for JavaFX also means to deal with its closeness, its bugs, its annoying
design decisions. Many times I've honestly been on the verge of giving up because sometimes it's really too much
stress to handle.
But, today MaterialFX is a great library, supported by many people and I'm proud of it.
If you are using MaterialFX in your projects and feel like it, I recently
activated GitHub Sponsors so
you can easily donate/sponsor.
(If you want your github page to be linked here and you didn't specify your username in the donation, feel free to contact me by email and tell me. Also contact me if for some some reason you don't want to be listed here)
Thank you very very much to all supporters, to all people who contribute to the project, to all people that thanked me, you really made my day
275 followers · starred May 2021
185 followers · starred Dec 2021
201 followers · starred May 2021
56 followers · starred May 2024