Git Product home page Git Product logo

materialfx's Introduction

HitCount GitHub Workflow Status Sonatype Nexus (Releases) javadoc GitHub issues GitHub pull requests GitHub JFXCentral


Logo

MaterialFX

MaterialFX is an open source Java library which provides material design components for JavaFX
Explore the wiki »

Download Latest Demo · Report Bug · Request Feature

Table of Contents

Important notes

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

About The Project and History of JavaFX

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:

  • FXML and SceneBuilder, A designer can code in FXML or use JavaFX Scene Builder to interactively design the graphical user interface (GUI). Scene Builder generates FXML markup that can be ported to an IDE where a developer can add the business logic.
  • Built-in UI controls and CSS, JavaFX provides all the major UI controls required to develop a full-featured application. Components can be skinned with standard Web technologies such as CSS.
  • Self-contained application deployment model. Self-contained application packages have all the application resources and a private copy of the Java and JavaFX runtimes. They are distributed as native installable packages and provide the same installation and launch experience as native applications for that operating system. JavaFX is a software platform for creating and delivering desktop applications, as well as rich Internet applications (RIAs) that can run across a wide variety of devices.

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 ...).

About The Logo

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.

Preview GIFs

Imgur Link: Gallery

Buttons
Buttons

Check Boxes, Radio Buttons and Toggles
Checkboxes

Combo Boxes
Comboboxes

Dialogs
Dialogs

Fields
Fields

Lists
Listviews

Notifications
Notifications

Pickers
Pickers

Progress
Progress

Scroll Panes
Scrollpanes

Sliders
Sliders

Stepper
Stepper

Tables
Tableviews

Getting Started

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.

Build

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.

Usage

Gradle
repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.github.palexdev:materialfx:11.17.0'
}
Maven
<dependency>
    <groupId>io.github.palexdev</groupId>
    <artifactId>materialfx</artifactId>
    <version>11.17.0</version>
</dependency>

Documentation

You can read MaterialFX's documentation at javadoc.io

Changelog

See the CHANGELOG file for a list of changes per version.

Roadmap

See the Open Issues for a list of proposed features (and known issues) .
See the ROADMAP for a list of implemented and upcoming features.

Theming System

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:

  1. The little buggers didn't think of nested custom controls. For example, if a custom control(parent) has a skin that uses other custom controls(children), the user agent of the parent will be completely ignored by the children, the result is a bunch of children that cannot be styled in any way unless you create a custom skin yourself. A fix I implemented for this in the past, was to override inline the 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)
  2. For some reason, sometimes stylesheets provided by the user were half or completely ignored leading to half/not styled(as intended) custom controls. This was the most annoying issue, as the causes would vary from case to case, not always there was an easy/feasible solution, a nightmare, really

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

Previous System (changed because of performance issues) An interface called `Theme` allows users to define custom themes entries. It defines the bare minimum for a theme, its path and a way to load it. There are two implementations of this interface:
  1. 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...
  2. 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 style

MFXThemeManager is a utility class that will help the user add/set themes and stylesheets (which implement Theme) on nodes or scenes.

Pros

  • The biggest pro is to have a more reliable styling system. With this users shouldn't hava any issue anymore while styling MaterialFX controls with their custom stylesheets. Of course, I consider the system experimental, I don't expect to not have even a single report about CSS bugs, but they should be way less and much easier to fix
  • Another pro is to have less code duplication as now I don't need to override the infamous getUserAgentStylesheet() anymore anywhere
  • This change should have also impacted on memory usage in a good way as now controls do not store the "url" to their stylesheet anymore

Cons

  • One con is that now themes must be managed by the user. Since controls are not styled by default, the user must use the aforementioned manager or enumerators to load/add the themes on the App.
    The preferred way to do so would be to add the themes/stylesheets on the root scene, like this:
    public class App extends Application {
    
      @Override
      public void start(Stage stage) {
       ...
       Scene scene = ...;
       MFXThemeManager.addOn(scene, Themes.DEFAULT, Themes.LEGACY);
      }
    }
  • Another con that derives from the above example are dialogs/popups or any separate stage/scene. Since you are applying the themes on the primary stage's scene, it means that all other scenes will be un-styled. You have to add the Themes on every separate scene. To simplify things, MaterialFX automatically applies the Themes on its dialogs and popups, but since now they are added to the getStylesheets() list it's easy to remove them and define your own
  • The last con I can think of is SceneBuilder. As of now there is no support for it, I have some ideas on how to style controls inside of it though. The issue is that even if I figure out a way, I doubt the system will be flexible enough. What I mean is, I can probably set the default themes on the SceneBuilder' scene, but it's very unlikely there will be a way to choose which themes/stylesheets will be applied.
    Since version 11.15.0, MaterialFX controls are capable of detecting if they are being used in SceneBuilder and can automatically style themselves. From my little testings, it seems that this doesn't break the styling system in any way, I was able to style a button by adding a custom stylesheet on itself or on its parent. There's also an emergency system to completely shut down the SceneBuilder integration, more info here: Themable


New system The best way to style a JavaFX app is to set its User-Agent Stylesheet by calling `Application.setUserAgentStylesheet(...)`. The issue with this is that JavaFX's default theme is overridden, and so, any other non-custom control will not be styled. This is good if you are going to use only custom controls, but obviously bad if you are going to use JavaFX's controls or any other control from other libraries that rely on the JavaFX's default theme. There is no easy way around this. There is a proposal to enhance the system on the JavaFX page, but it won't come anytime soon. So, I came up with a pretty decent workaround. If I can't set multiple User-Agents then I will build a single one. So, let's see how the API works.

An 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:

  1. 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.
  2. 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.css

Now, 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
  1. First and foremost, the build has to know which themes/stylesheets you want to combine, add them through the themes(...) method.
  2. Themes are allowed to have assets. You see, when they are combined into one single stylesheets, resources are likely to fail loading. So, fonts, images and such will not be available anymore. To overcome this issue, there's only one way, deploying all the needed resources on the disk. Assets should be packed in a .zip file, and you should be very careful at the structure inside it. When extracting the files the structure will be honored.
  3. Deploying the assets in most cases is not enough. Let's say a CSS file has this statement @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.css

Pros

  • The biggest pro is to have a more reliable styling system. With this, users shouldn't have any issue anymore while styling MaterialFX controls with their custom stylesheets. Of course, I consider the system experimental, I don't expect to not have even a single report about CSS bugs, but they should be way less and much easier to fix. Since the theme is set as the app's global User-Agent, it will be applied on all the Stages/Scenes of the app, which is great
  • Another pro is to have less code duplication as now I don't need to override the infamous getUserAgentStylesheet() anymore anywhere
  • This change should have also impacted on memory usage in a good way as now controls do not store the "url" to their stylesheet anymore
  • Potentially, you could now create a single theme, that is applied consistently everywhere in your apps, with as much stylesheets as you want

Cons

  • The main con is that now theming must be managed by the user. Since controls are not styled by default anymore, the user must use the 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).
  • The system is fragile and naive. CSS files need to be well written and formatted, and even in that case, there may still be issues while parsing or once the aio User-Agent is set.
  • The generated theme won't be able to access "local" resources anymore. For this reason, themes now have to deploy assets if needed, which surely introduces some overhead. Not only that, for the previous point, resolving "local" assets to "absolute" assets may fail and can be hard to set up.
  • SceneBuilder integration is tricky and error/bug prone. MaterialFX controls are capable of detecting if they are being used in SceneBuilder and can automatically style themselves. From my little testings, it seems that this doesn't break the styling system in any way. I was able to style a button by adding a custom stylesheet on itself or on its parent. There's also an emergency system to completely shut down the SceneBuilder integration, more info here: Themable

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the GNU LGPLv3 License. See LICENSE for more information.

Contact

Alex - [email protected]

Discussions

Project Link: https://github.com/palexdev/MaterialFX

Donation

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.

Supporters:

(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)

  • Alaa Abu Zidan
  • Alex Hawk
  • Aloento
  • brr53
  • Eugen Gubin
  • Mauro de Wit
  • Mohammad Chaudhry (thank you very much for the huge donation, YOU are the legend)
  • Jtpatato21
  • Sourabh Bhat
  • stefanofornari (thank you very much for the big donation!)
  • Ultraviolet-Ninja
  • Yahia Rehab
  • Yiding He
  • Your name can be here by supporting me at this link, GitHub Sponsors

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

materialfx's People

Contributors

antoninhuaut avatar georgioyammine avatar gilad4 avatar glavo avatar infinite-dev22 avatar jbenak8 avatar laritello avatar martincousido avatar palexdev avatar stefanofornari avatar thisisverycool avatar yaya-dev-box avatar zayrexdev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

materialfx's Issues

MFXProgressBar not updating progress visually

Hi,

I am having an issue updating the progress bar to be any value besides indeterminate. I have run a debug on my application and verified the following:

  1. progressBar.setProgress( value ); is called from the JavaFX thread
  2. The internal progressBar.progress and progressBar.indeterminate values appear to be properly updated.

    image
  3. The value specified to progressBar.setProgress( value ) is either the indeterminate value, or is between 0.0 and 1.0.

    image
  4. I have verified that the standard JavaFX progress bar does not experience this behavior, when swapped with the MFXProgressBar (no other code changes)

Despite everything being called and set correctly (I believe), the progress bar always shows as indeterminate in my application.
image

Not working

I added it to gradle's dependencies but the module-info.java now is getting an error like Package .... reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base' and i can't use the library, also when i try to import something it seems like the package doesn't exists

Validators not updating

Hi, i'm using MaterialFX with TornadoFX on JDK 16 and it seems like the validators doesn't update when selecting another component and the message doesn't show either, i have downloaded the demo and it works but when using it on my project it doesn't so i assumed that there something wrong with my code:

fun MFXTextField.markAsRequired(): MFXTextField {
    validator.add(
        BindingUtils.toProperty(Bindings.createBooleanBinding({ return@createBooleanBinding !text.isNullOrBlank() }, textProperty())),
        "Ce champ est obligatoire"
    )
    isValidated = false
    return this
}

fun MFXTextField.markAsDoubleOnly(): MFXTextField {
    validator.add(
        BindingUtils.toProperty(Bindings.createBooleanBinding({ return@createBooleanBinding text != null && text.isDouble() }, textProperty())),
        "Type incorrecte, précisez un décimal"
    )
    isValidated = false
    return this
}```

ListView trackpad inertia too high

In the demo app, in the font resources section, there's a list view. Trying to scroll with the trackpad is quite hard because the friction is too low, so even a tiny swipe causes the list to fly all the way to the end. It requires a truly tiny swipe to move the list by less than the whole amount. It feels like the inertial physics of this control don't match the operating system defaults.

MFXProgressBar offset bar location after indeterminate

Hello,

I have noticed a bug that occurs in certain scenarios with the MFXProgressBar:

When the progress bar is set to indeterminate, then changed to a standard progress value, the location of the bar is sometimes not reset and the standard progress is offset as a result. This does not happen if the progress bar is never set to indeterminate.

ProgressBarIndeterminateToRegular

2021-06-08.09-35-17_Trim.mp4

How can I add a imageview (or other nodes) into a TreeCell ?

I note that in the demo ,there is no examples about treeView.
But I find the node MFXTreeView in the MaterialFX.
I had tried to use it, but not like the MFXTableView , it cannot use the function of setCellFactory to add the nodes like imageView and so on.
So, how can I do it ?
(I am a student from China , so my English is not so good.I am sorry about that.)

Issue - MFXTableView

Big tables should be scrollable
if you set in maxRowsCombo big integer the table will go out of the scene borders
the excepted result should be scrollable table with pagination

MFXRectangleToggleNode ignores graphic

might be intended but it seems counter-intuitive that MFXRectangleToggleNode ignores any graphic, if it is set. Example:

var mfx = new MFXRectangleToggleNode();
mfx.setGraphic(icon(FontAwesomeIcon.GLOBE));
root.add(mfx);

JFXToggleNode node = new JFXToggleNode();
node.setGraphic(icon(FontAwesomeIcon.GLOBE));
root.add(node);


ToggleButton javafx = new ToggleButton();
javafx.setGraphic(icon(FontAwesomeIcon.GLOBE));
root.add(javafx);

results in
image

using setLeading / Trailing icon fixes it, so it might be intentional though...

using leading/trailing though results in non-centered icon (if empty text):
image

Flowless, Help Wanted

The project has been recently updated. I always said that I would move Flowless out of the project because it needs ReactFX to be on the classpath which is a rather nasty dependency considering that it's not supported anymore, it's bad written and bad documented. However, many controls such as the new ComboBoxes and the new ListViews rely on Flowless and removing it would also mean to remove those new controls. At first, I even thought about it, but I in the end I decided that it is out of discussion. Those controls are way easier to manage compared to their JavaFX counterparts and while many still use legacy components, personally I always use the new ones because I know exactly how they work, and they are well documented.

So the point is, It would be really a great achievement to remove ReactFX from Flowless, but it definitely is a hard task. Flowless is highly dependent on ReactFX, the refactor will require time and knowledge on ReactFX. So I'm here to ask the community if there is someone that would actually try to do it.
The good news at least is that if you don't have ReactFX on the classpath components based on Flowless won't work, but the rest of the library will.

Fluent API on components

It would be great to have the possibility to use Java's fluent API on all components. If you create a button, you won't have to do:

MFXButton loginButton = new MFXButton();

loginButton.setText("Login");
loginButton.setGraphic(new FontIcon("fas-sign-in-alt"));
loginButton.setButtonType(ButtonType.RAISED);
loginButton.setTranslateY(50);
loginButton.setGraphicTextGap(10);
loginButton.getStyleClass().add("some-class");

but instead:

MFXButton loginButton = new MFXButton()
    .setText("Login")
    .setGraphic(new FontIcon("fas-sign-in-alt"))
    .setButtonType(ButtonType.RAISED)
    .setTranslateY(50)
    .setGraphicTextGap(10)
    .getStyleClass().add("some-class");

This would make the code cleaner and the creation of new elements a lot easier.

ComboBox styling

Hi,
I am trying to change ComboBox style, in particular I'd like to replace the purple with something else, but the below css (I have replaced the purple occurrences with black) just does not work. Any ideas?

CSS (combostyle.css in my resources folder)

@import "Fonts.css";
.mfx-combo-box {
    -mfx-line-color: black;
    -mfx-unfocused-line-color: black;
    -mfx-line-stroke-width: 2px;
    -fx-background-color: transparent;
    -fx-background-radius: 3 3 0 0;
    -fx-border-width: 1.5;
}

.mfx-combo-box .mfx-icon-wrapper .mfx-ripple-generator {
    -mfx-ripple-color: black;
}

.mfx-combo-box .mfx-icon-wrapper .mfx-font-icon {
    -mfx-color: black;
}

.mfx-combo-box:focused .mfx-icon-wrapper .mfx-font-icon {
    -mfx-color: black;
}

.mfx-combo-box:editor .mfx-icon-wrapper .mfx-font-icon {
    -mfx-color: black;
}

.mfx-list-view {
    -fx-background-color: white;
    -fx-border-color: #A4B1B6;
    -fx-background-insets: 0 -1 0 -1;
    -fx-border-insets: 0 -1 0 -1;

    -mfx-track-color: transparent;
    -mfx-thumb-color: black;
    -mfx-thumb-hover-color: black;
}

.mfx-list-view .mfx-list-cell:hover {
    -fx-background-color: black;
    -fx-border-color: black;
}

.mfx-list-view .mfx-list-cell:selected {
    -fx-background-color: black;
    -fx-border-color: black;
}

.mfx-combo-box:invalid {
    -mfx-line-color: #EF6E6B;
    -mfx-unfocused-line-color: #EF6E6B;
}

.mfx-combo-box:invalid .mfx-icon-wrapper .mfx-font-icon{
    -mfx-color: #EF6E6B;
}

.mfx-combo-box:focused:invalid .mfx-icon-wrapper .mfx-font-icon{
    -mfx-color: #EF6E6B;
}

.mfx-combo-box:focused:editor:invalid .mfx-icon-wrapper .mfx-font-icon{
    -mfx-color: #EF6E6B;
}

.mfx-combo-box:invalid .mfx-label {
    -mfx-text-fill: #EF6E6B;
}

.mfx-combo-box:invalid .mfx-label:prompt {
    -mfx-text-fill: #EF6E6B;
}

.mfx-combo-box .validate-label {
    -fx-background-color: transparent;
    -fx-font-family: "Open Sans SemiBold";
    -fx-font-size: 11;
    -fx-text-fill: #EF6E6B;
}

.mfx-combo-box .unfocused-line {
    -fx-stroke: -mfx-unfocused-line-color;
}

.mfx-combo-box .focused-line {
    -fx-stroke: -mfx-line-color;
}

.mfx-combo-box:invalid .unfocused-line {
    -fx-stroke: #EF6E6B;
}

.mfx-combo-box:invalid .focused-line {
    -fx-stroke: #EF6E6B;
}

.mfx-combo-box .unfocused-line {
    -fx-stroke: -mfx-unfocused-line-color;
}

.mfx-combo-box .focused-line {
    -fx-stroke: -mfx-line-color;
}

.mfx-combo-box:invalid .unfocused-line {
    -fx-stroke: #EF6E6B;
}

.mfx-combo-box:invalid .focused-line {
    -fx-stroke: #EF6E6B;
}

.mfx-combo-box .unfocused-line {
    -fx-stroke: -mfx-unfocused-line-color;
}

.mfx-combo-box .focused-line {
    -fx-stroke: -mfx-line-color;
}

.mfx-combo-box:invalid .unfocused-line {
    -fx-stroke: #EF6E6B;
}

.mfx-combo-box:invalid .focused-line {
    -fx-stroke: #EF6E6B;
}

CODE

var modeBox = new MFXComboBox<String>();
modeBox.setLineColor(Paint.valueOf("#00000000"));

modeBox.getStyleClass().add("combostyle.css");
modeBox.setItems(FXCollections.observableArrayList(modes));
modeBox.setId("targetMode");

modeBox.selectedValueProperty().bindBidirectional(target.mode);
modeBox.getSelectionModel().selectFirst();
...

Any help or suggestion is appreciated :)

@palexdev great job btw!

Module reactfx not found, required by MaterialFX

I'm building a modular application and I am getting the following error.
Error occurred during initialization of boot layer java.lang.module.FindException: Module reactfx not found, required by MaterialFX.
Error is identical for gradle and IDE runs

Reactfx has definitely been downloaded by gradle as I can see it in the external libraries section. Below is my Gradle build file

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.5.10'
    id 'application'
}
group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}
def javaFXPlatform = getJavaFXPlatform()
def javaFXVersion = "16"
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib"
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation 'io.github.palexdev:materialfx:11.11.1'
    implementation "org.openjfx:javafx-base:${javaFXVersion}:${javaFXPlatform}"
    implementation "org.openjfx:javafx-controls:${javaFXVersion}:${javaFXPlatform}"
    implementation "org.openjfx:javafx-graphics:${javaFXVersion}:${javaFXPlatform}"
    implementation "org.openjfx:javafx-fxml:${javaFXVersion}:${javaFXPlatform}"
}

application {
    mainModule.set('main')
    mainClass.set('application.MainApp')
}
test {
    useJUnitPlatform()
}
java {
    modularity.inferModulePath.set(true)
}
private static String getJavaFXPlatform() {
    return 'win'
}

And my module-info.java file

module main { requires MaterialFX; requires javafx.graphics; requires javafx.fxml; requires javafx.controls; requires kotlin.stdlib; opens application; }

JavaFX is working fine without MaterialFX. Thank you, I really appreciate all the work you've put in to this library, i'm really hoping I can fix this issue and be rid of Jfoenix forever!

Cannot run the demo

Trying to build from source using ./gradlew run with Java 11, and I get:

> Task :demo:run FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /Users/mike/Library/Caches/gradle-build/MaterialFX/demo/classes/java/main
Caused by: java.lang.module.InvalidModuleDescriptorException: null: unnamed package

Just wanna say keep up the good work!

Please close this issue whenever!

But I just want to give some morale because i'm loving the look of the project and your changes in staging :)

I'll be switching from JFoenix <3

Unsupported JavaFX configuration

I upgraded to new version 11.11.0
but now I receive this error
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @43586eb9'
Environment : JDK 11
non modular app

MFXButton is not accepting effects

when you use a mfxbutton in scenebuilder and try to set effect for it from scenebuilder it does not work not accepting any effct : dropshadow , glow ,Bloom ... etc

Notification on minimized screen

There is a issue when we a long task and we minimized the app
The notification will not displayed because he don't have and owner window
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Owner window must not be null

Custom TableView

Maybe I am missing something but there is any option to add customized column with buttons ?

Slider control

Hi,

Are there any plans to provide a Slider control?

Thank you!

Unable to Change the Color of the Text in MFXTextField and MFXPasswordField

Hello, I am using the MaterialFX for my Project and I am using the Dark UI. So I want to change the color of the text to white based colors of the MFXTextField and MFXPasswordField. Will you please tell me, Is there any way to change the color of the text in the MFXTextField and MFXPasswordField?

Thanks in Advance.

MFXTableView Filters

I think it will be great if you can add dynamically all the table columns to the filters options
then the user can filter by custom columns
similar to this
SCN_Filter

no documentation on how to use the ripple effect ?

can you provide an example how to use the ripple effect
i use
MFXCircleRippleGenerator ripple = new MFXCircleRippleGenerator (test2pane) ;
testPane.getChildren().add(test2pane);
but it does not work

Runtime Exception while Limiting Characters in MFXPasswordField

When the -mfx-text-limit is set to some value, then while running, if the text is entered greater than the spcefied value, it raises an Runtime Exception with the error a bound value cannot be set. and it also allows to enter the values greater than the specified value if we catch that exception. Please help me to resolve the issue.

found a bug when using mfxdatepicker

when you use mfxdatepicker and click input date and enter incorect date (string , or incorect format date ) the ide generates a error
This probably only happens in java 16 i tested in java 11 and the error is not generated
java.time.format.DateTimeParseException: Text '11a' could not be parsed at index 2
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954)
at java.base/java.time.LocalDate.parse(LocalDate.java:430)
at [email protected]/io.github.palexdev.materialfx.skins.MFXDatePickerContent.lambda$buildField$17(MFXDatePickerContent.java:653)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.graphics/javafx.stage.PopupWindow$PopupEventRedirector.handleKeyEvent(PopupWindow.java:1001)
at javafx.graphics/javafx.stage.PopupWindow$PopupEventRedirector.handleRedirectedEvent(PopupWindow.java:973)
at javafx.base/com.sun.javafx.event.EventRedirector.dispatchCapturingEvent(EventRedirector.java:106)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchCapturingEvent(CompositeEventDispatcher.java:43)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:52)
at javafx.base/com.sun.javafx.event.EventRedirector.redirectEvent(EventRedirector.java:124)
at javafx.base/com.sun.javafx.event.EventRedirector.dispatchCapturingEvent(EventRedirector.java:103)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchCapturingEvent(CompositeEventDispatcher.java:43)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:52)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$KeyHandler.process(Scene.java:4064)
at javafx.graphics/javafx.scene.Scene.processKeyEvent(Scene.java:2123)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2591)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
at javafx.graphics/com.sun.glass.ui.View.handleKeyEvent(View.java:547)
at javafx.graphics/com.sun.glass.ui.View.notifyKey(View.java:971)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:831)

Request for MFXDatePicker

Hi, I would like to request a date picker for MaterialFX. The JFXDatePicker that I used before JDK 11 worked fine, until I started using JDK 11 and JavaFX 11. Now I need to use an add-opens VM option and multiple ones are needed for it to work. However, my favorite IDE, NetBeans, doesn't allow me to have multiple add-opens, so could you please add a MFXDatePicker? Thanks!

Restrictive license

Would you consider relicensing this project to be more permissive? Something like the MIT license or Apache 2.0 license would be wonderful. I mention this because I am unable to use this project with the current GPL 3.0 license.

MFXPasswordField's getMFXContextMenu() returns null

I'm trying to change the style of MFXPasswordField's MFXContectMenu using CSS but the method getMFXContextMenu() returns null, also I can't create a new MFXContectMenu and use it instead because setMFXContextMenu() seems to not work, maybe something with the control's Skin? MFXTextFieldField's methods work.

Thanks in advance, nice library :)

Encountered some environmental problems

I don't know exactly what it is, but I tried with java11 and 16 without success.

Great project, looking forward to more detailed instructions and tutorials for newbies

Password in MFXTextField

Greetings,

I am looking to add the capability to login to my application using a standard username/password combination. I've switched everything over to MaterialFX, although I am stuck on finding out how to make my password field. Right now, I have a MFXTextField, but it doesn't look like there is a way to obscure the characters.

Is there a way to make the text field work for passwords, or can an MFXPasswordField be added?

Bug - Scroll bar issue with legacy TableView

I was trying out some things in the demo, and I got to the legacy TableView, where I dragged one column far enough that the horizontal scroll bar would show up, and then I dragged it back, and the horizontal scroll bar was still there.
Screenshot of bug

License Agreement

Any chance you will change your licence agreement in the future so I can consider this library for my closed source projects?

css fill-text not applied on MfxButton

apparently, -fx-text-fill is not applied on a button-text:
image

i used this code

public class Test extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        var root = vbox(); //simple VBox
        Scene mainScene = new Scene(root);

        mainScene.getStylesheets().clear();
        mainScene.getStylesheets().add("/mfx/light.css");

        root.add(new MFXButton("mfxButton"));
        root.add(new JFXButton("jfxButton"));
        root.add(new Button("plainButton"));

        primaryStage.setScene(mainScene);
        primaryStage.show();
    }
}

with this styling:

.button {
    -fx-text-fill: red;
    -fx-background-color: yellow;
}

manually setting via Button::setTextFill works though

Dialogs not working and PasswordField bug

MFXDialog dialog = new MFXDialog(); dialog.setContent("test"); dialog.show();

When i try to show a dialog i get this error:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1862)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1729)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8889)
at javafx.scene.control.Button.fire(Button.java:203)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3856)
at javafx.scene.Scene.processMouseEvent(Scene.java:1851)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2584)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
at com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at com.sun.glass.ui.View.notifyMouse(View.java:942)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
... 46 more
Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.layout.Pane.widthProperty()" because "parent" is null
at io.github.palexdev.materialfx.effects.MFXScrimEffect.modalScrim(MFXScrimEffect.java:77)
at io.github.palexdev.materialfx.controls.MFXDialog.show(MFXDialog.java:153)
at me.darkboy.controllers.RegisterController.onRegisterClick(RegisterController.java:28)
... 58 more
Caused by: java.lang.reflect.InvocationTargetException

Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.layout.Pane.widthProperty()" because "parent" is null

When i use a passwordfield with a length limit and i get to the end, if i continue to type after reaching the limit it still allows me to type and i get this error:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: A bound value cannot be set.
at javafx.scene.control.TextInputControl$TextProperty.set(TextInputControl.java:1391)
at javafx.scene.control.TextInputControl.setText(TextInputControl.java:361)
at io.github.palexdev.materialfx.controls.MFXTextField.lambda$addListeners$3(MFXTextField.java:183)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1459)
at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1463)
at javafx.scene.control.TextInputControl$TextProperty.controlContentHasChanged(TextInputControl.java:1402)
at javafx.scene.control.TextInputControl.lambda$new$0(TextInputControl.java:146)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:136)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.scene.control.TextField$TextFieldContent.insert(TextField.java:91)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:1264)
at javafx.scene.control.TextInputControl.filterAndSet(TextInputControl.java:1229)
at javafx.scene.control.TextInputControl$TextProperty.doSet(TextInputControl.java:1480)
at javafx.scene.control.TextInputControl$TextProperty$Listener.invalidated(TextInputControl.java:1503)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:136)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.binding.StringBinding.invalidate(StringBinding.java:175)
at com.sun.javafx.binding.BindingHelperObserver.invalidated(BindingHelperObserver.java:52)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:136)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
at io.github.palexdev.materialfx.skins.MFXPasswordFieldSkin.setFakeText(MFXPasswordFieldSkin.java:330)
at io.github.palexdev.materialfx.skins.MFXPasswordFieldSkin.lambda$setListeners$1(MFXPasswordFieldSkin.java:113)
at com.sun.javafx.event.CompositeEventHandler$NormalEventFilterRecord.handleCapturingEvent(CompositeEventHandler.java:321)
at com.sun.javafx.event.CompositeEventHandler.dispatchCapturingEvent(CompositeEventHandler.java:98)
at com.sun.javafx.event.EventHandlerManager.dispatchCapturingEvent(EventHandlerManager.java:221)
at com.sun.javafx.event.EventHandlerManager.dispatchCapturingEvent(EventHandlerManager.java:180)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchCapturingEvent(CompositeEventDispatcher.java:43)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:52)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$KeyHandler.process(Scene.java:4064)
at javafx.scene.Scene.processKeyEvent(Scene.java:2123)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2591)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
at com.sun.glass.ui.View.handleKeyEvent(View.java:547)
at com.sun.glass.ui.View.notifyKey(View.java:971)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:831)

i am using Java 16

How can I change the label text in the tableView?

How should I modify the text in the red box?(Without modify the jar file or remake the jar from the source)
Can I add a listenner when user change the settings of the RowsPerPage?
I am a student from China who is studying your progrom to finish my java application.

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.