Преглед на файлове

:memo: Reformat code

Signed-off-by: palexdev <alessandro.parisi406@gmail.com>
palexdev преди 3 години
родител
ревизия
fcdad3ca03
променени са 100 файла, в които са добавени 7243 реда и са изтрити 7217 реда
  1. 8 6
      README.md
  2. 1 1
      build.gradle
  3. 11 11
      demo/src/main/java/io/github/palexdev/materialfx/demo/MFXDemoResourcesLoader.java
  4. 3 2
      demo/src/main/java/io/github/palexdev/materialfx/demo/controllers/DialogsController.java
  5. 1 1
      demo/src/main/java/io/github/palexdev/materialfx/demo/controllers/ProgressController.java
  6. 6 2
      demo/src/main/java/io/github/palexdev/materialfx/demo/controllers/TableViewsController.java
  7. 12 12
      demo/src/main/java/module-info.java
  8. 21 21
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Buttons.css
  9. 3 3
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/ChecksRadiosToggles.css
  10. 2 2
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/ComboBoxes.css
  11. 11 11
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Common.css
  12. 43 43
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Demo.css
  13. 2 2
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/MFXColors.css
  14. 2 2
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Pickers.css
  15. 9 9
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Progress.css
  16. 18 18
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Sliders.css
  17. 6 6
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Stepper.css
  18. 10 10
      demo/src/main/resources/io/github/palexdev/materialfx/demo/css/TextFields.css
  19. 179 179
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fonts/Fonts.css
  20. 6 6
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Buttons.fxml
  21. 102 102
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ChecksRadiosToggles.fxml
  22. 69 69
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ComboBoxes.fxml
  23. 43 36
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Demo.fxml
  24. 18 13
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/FontResources.fxml
  25. 71 71
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ListViews.fxml
  26. 57 57
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Notifications.fxml
  27. 28 28
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Pickers.fxml
  28. 64 64
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Progress.fxml
  29. 29 29
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ScrollPanes.fxml
  30. 52 52
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Sliders.fxml
  31. 19 19
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Stepper.fxml
  32. 3 3
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/TableViews.fxml
  33. 68 66
      demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/TextFields.fxml
  34. 21 21
      demo/src/test/java/BorderWithGap.java
  35. 9 9
      demo/src/test/java/FilterPaneTest.java
  36. 1 1
      demo/src/test/java/FloatingStyle.java
  37. 4 4
      demo/src/test/java/Launcher.java
  38. 155 155
      demo/src/test/java/MFXLabelRework.java
  39. 159 159
      demo/src/test/java/MFXLabelSkinRework.java
  40. 47 47
      demo/src/test/java/NotificationsTest.java
  41. 49 49
      demo/src/test/java/PopupTest.java
  42. 42 42
      demo/src/test/java/collections/TransformableListTest.java
  43. 28 28
      demo/src/test/java/combobox/ComboBoxTest.java
  44. 83 83
      demo/src/test/java/properties/SynchronizedBooleanTests.java
  45. 55 55
      demo/src/test/java/properties/SynchronizedDoubleTests.java
  46. 55 55
      demo/src/test/java/properties/SynchronizedFloatTests.java
  47. 113 113
      demo/src/test/java/properties/SynchronizedIntegerTests.java
  48. 55 55
      demo/src/test/java/properties/SynchronizedLongTests.java
  49. 55 56
      demo/src/test/java/properties/SynchronizedObjectTests.java
  50. 55 55
      demo/src/test/java/properties/SynchronizedStringTests.java
  51. 102 102
      demo/src/test/java/prototipes/FloatingTextPrototype.java
  52. 85 85
      demo/src/test/java/treeview/NumberUtilsTests.java
  53. 358 358
      demo/src/test/java/treeview/TreeViewTests.java
  54. 2 2
      materialfx/build.gradle
  55. 10 10
      materialfx/src/main/java/io/github/palexdev/materialfx/MFXResourcesLoader.java
  56. 41 41
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/AnimationsData.java
  57. 25 25
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/BiPredicateBean.java
  58. 69 69
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/CustomBounds.java
  59. 70 70
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/FilterBean.java
  60. 10 10
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/MFXSnapshotWrapper.java
  61. 157 157
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/NumberRange.java
  62. 81 81
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/PopupPositionBean.java
  63. 34 34
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/PositionBean.java
  64. 46 46
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/TransitionPositionBean.java
  65. 24 24
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/NumberRangeProperty.java
  66. 29 28
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/base/ResettableProperty.java
  67. 65 65
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/base/SynchronizedProperty.java
  68. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableBooleanProperty.java
  69. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableDoubleProperty.java
  70. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableFloatProperty.java
  71. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableIntegerProperty.java
  72. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableLongProperty.java
  73. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableObjectProperty.java
  74. 77 77
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableStringProperty.java
  75. 16 16
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/styleable/StyleableBooleanProperty.java
  76. 184 184
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedBooleanProperty.java
  77. 183 183
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedDoubleProperty.java
  78. 183 183
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedFloatProperty.java
  79. 183 183
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedIntegerProperty.java
  80. 182 182
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedLongProperty.java
  81. 183 182
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedObjectProperty.java
  82. 183 183
      materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedStringProperty.java
  83. 5 5
      materialfx/src/main/java/io/github/palexdev/materialfx/bindings/BiBindingHelper.java
  84. 106 106
      materialfx/src/main/java/io/github/palexdev/materialfx/bindings/BindingHelper.java
  85. 29 29
      materialfx/src/main/java/io/github/palexdev/materialfx/bindings/BooleanListBinding.java
  86. 8 3
      materialfx/src/main/java/io/github/palexdev/materialfx/bindings/base/AbstractBindingHelper.java
  87. 23 23
      materialfx/src/main/java/io/github/palexdev/materialfx/collections/ChangeHelper.java
  88. 48 48
      materialfx/src/main/java/io/github/palexdev/materialfx/collections/CircularQueue.java
  89. 146 146
      materialfx/src/main/java/io/github/palexdev/materialfx/collections/GenericAddRemoveChange.java
  90. 274 274
      materialfx/src/main/java/io/github/palexdev/materialfx/collections/ObservableStack.java
  91. 184 184
      materialfx/src/main/java/io/github/palexdev/materialfx/collections/TransformableList.java
  92. 296 297
      materialfx/src/main/java/io/github/palexdev/materialfx/collections/TransformableListWrapper.java
  93. 31 31
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/BoundLabel.java
  94. 317 317
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXButton.java
  95. 189 189
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckListView.java
  96. 129 129
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckTreeItem.java
  97. 29 29
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckTreeView.java
  98. 149 149
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckbox.java
  99. 124 124
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXFilterPane.java
  100. 149 149
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXIconWrapper.java

+ 8 - 6
README.md

@@ -37,10 +37,10 @@
 * [About the Project and History of JavaFX](#about-the-project-and-history-of-javafx)
 * [Some GIFs](#preview-gifs)
 * [Getting Started](#getting-started)
-  * [Build](#build)
-  * [Usage](#usage)
-    * [Gradle](#gradle)
-    * [Maven](#maven)
+    * [Build](#build)
+    * [Usage](#usage)
+        * [Gradle](#gradle)
+        * [Maven](#maven)
 * [Roadmap](#roadmap)
 * [Contributing](#contributing)
 * [License](#license)
@@ -74,8 +74,10 @@ That's where this project comes in. The aim of my project is to bring components
 Google's material design guidelines to JavaFX. The second purpose is to provide a successor to the already
 available [JFoenix](https://github.com/jfoenixadmin/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 ...).
+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 ...).
 
 <!-- PREVIEW GIFS -->
 

+ 1 - 1
build.gradle

@@ -15,7 +15,7 @@ subprojects {
 
     javafx {
         version = "17.0.1"
-        modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.media', 'javafx.swing', 'javafx.web' ]
+        modules = ['javafx.controls', 'javafx.fxml', 'javafx.media', 'javafx.swing', 'javafx.web']
     }
 }
 

+ 11 - 11
demo/src/main/java/io/github/palexdev/materialfx/demo/MFXDemoResourcesLoader.java

@@ -27,19 +27,19 @@ import java.net.URL;
  */
 public class MFXDemoResourcesLoader {
 
-    private MFXDemoResourcesLoader() {
-    }
+	private MFXDemoResourcesLoader() {
+	}
 
-    public static URL loadURL(String path) {
-        return MFXDemoResourcesLoader.class.getResource(path);
-    }
+	public static URL loadURL(String path) {
+		return MFXDemoResourcesLoader.class.getResource(path);
+	}
 
-    public static String load(String path) {
-        return loadURL(path).toString();
-    }
+	public static String load(String path) {
+		return loadURL(path).toString();
+	}
 
-    public static InputStream loadStream(String name) {
-        return MFXDemoResourcesLoader.class.getResourceAsStream(name);
-    }
+	public static InputStream loadStream(String name) {
+		return MFXDemoResourcesLoader.class.getResourceAsStream(name);
+	}
 
 }

+ 3 - 2
demo/src/main/java/io/github/palexdev/materialfx/demo/controllers/DialogsController.java

@@ -42,7 +42,8 @@ public class DialogsController {
 					.get();
 
 			dialogContent.addActions(
-					Map.entry(new MFXButton("Confirm"), event -> {}),
+					Map.entry(new MFXButton("Confirm"), event -> {
+					}),
 					Map.entry(new MFXButton("Cancel"), event -> dialog.close())
 			);
 
@@ -91,6 +92,6 @@ public class DialogsController {
 		);
 
 		if (styleClass != null)
-		dialogContent.getStyleClass().add(styleClass);
+			dialogContent.getStyleClass().add(styleClass);
 	}
 }

+ 1 - 1
demo/src/main/java/io/github/palexdev/materialfx/demo/controllers/ProgressController.java

@@ -38,7 +38,7 @@ public class ProgressController implements Initializable {
 		createAndPlayAnimation(determinateBar);
 		createAndPlayAnimation(determinateSpinner);
 	}
-	
+
 	private void createAndPlayAnimation(ProgressIndicator indicator) {
 		Animation a1 = TimelineBuilder.build()
 				.add(

+ 6 - 2
demo/src/main/java/io/github/palexdev/materialfx/demo/controllers/TableViewsController.java

@@ -47,7 +47,9 @@ public class TableViewsController implements Initializable {
 
 		nameColumn.setRowCellFactory(person -> new MFXTableRowCell<>(Person::getName));
 		surnameColumn.setRowCellFactory(person -> new MFXTableRowCell<>(Person::getSurname));
-		ageColumn.setRowCellFactory(person -> new MFXTableRowCell<>(Person::getAge) {{ setAlignment(Pos.CENTER_RIGHT); }});
+		ageColumn.setRowCellFactory(person -> new MFXTableRowCell<>(Person::getAge) {{
+			setAlignment(Pos.CENTER_RIGHT);
+		}});
 		ageColumn.setAlignment(Pos.CENTER_RIGHT);
 
 		table.getTableColumns().addAll(nameColumn, surnameColumn, ageColumn);
@@ -68,7 +70,9 @@ public class TableViewsController implements Initializable {
 
 		idColumn.setRowCellFactory(device -> new MFXTableRowCell<>(Device::getID));
 		nameColumn.setRowCellFactory(device -> new MFXTableRowCell<>(Device::getName));
-		ipColumn.setRowCellFactory(device -> new MFXTableRowCell<>(Device::getIP) {{ setAlignment(Pos.CENTER_RIGHT); }});
+		ipColumn.setRowCellFactory(device -> new MFXTableRowCell<>(Device::getIP) {{
+			setAlignment(Pos.CENTER_RIGHT);
+		}});
 		ownerColumn.setRowCellFactory(device -> new MFXTableRowCell<>(Device::getOwner));
 		stateColumn.setRowCellFactory(device -> new MFXTableRowCell<>(Device::getState));
 		ipColumn.setAlignment(Pos.CENTER_RIGHT);

+ 12 - 12
demo/src/main/java/module-info.java

@@ -1,18 +1,18 @@
 module MaterialFX.Demo {
-    requires MaterialFX;
+	requires MaterialFX;
 
-    requires jdk.localedata;
+	requires jdk.localedata;
 
-    requires javafx.controls;
-    requires javafx.fxml;
-    requires javafx.graphics;
-    requires javafx.media;
+	requires javafx.controls;
+	requires javafx.fxml;
+	requires javafx.graphics;
+	requires javafx.media;
 
-    requires fr.brouillard.oss.cssfx;
-    requires org.kordamp.ikonli.javafx;
-    requires org.kordamp.ikonli.fontawesome5;
-    requires org.scenicview.scenicview;
+	requires fr.brouillard.oss.cssfx;
+	requires org.kordamp.ikonli.javafx;
+	requires org.kordamp.ikonli.fontawesome5;
+	requires org.scenicview.scenicview;
 
-    opens io.github.palexdev.materialfx.demo;
-    opens io.github.palexdev.materialfx.demo.controllers;
+	opens io.github.palexdev.materialfx.demo;
+	opens io.github.palexdev.materialfx.demo.controllers;
 }

+ 21 - 21
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Buttons.css

@@ -3,53 +3,53 @@
 @import 'MFXColors.css';
 
 .mfx-button {
-    -fx-font-family: 'Visby Round CF Medium';
-    -fx-text-fill: -mfx-text-he;
+	-fx-font-family: 'Visby Round CF Medium';
+	-fx-text-fill: -mfx-text-he;
 }
 
 .mfx-button .mfx-ripple-generator {
-    -mfx-ripple-radius: 40;
-    -mfx-auto-clip: true;
+	-mfx-ripple-radius: 40;
+	-mfx-auto-clip: true;
 }
 
 .mfx-button .text {
-    -fx-font-smoothing-type: lcd;
+	-fx-font-smoothing-type: lcd;
 }
 
 #custom {
-    -fx-background-color: -mfx-purple;
-    -fx-text-fill: white
+	-fx-background-color: -mfx-purple;
+	-fx-text-fill: white
 }
 
 .outline-button {
-    -fx-background-color: transparent;
-    -fx-border-color: -mfx-purple;
-    -fx-border-radius: 3;
+	-fx-background-color: transparent;
+	-fx-border-color: -mfx-purple;
+	-fx-border-radius: 3;
 
-    -fx-text-fill: -mfx-purple;
+	-fx-text-fill: -mfx-purple;
 }
 
 .outline-button:hover,
 .outline-button:focused {
-    -fx-background-color: -mfx-purple;
-    -fx-text-fill: white;
+	-fx-background-color: -mfx-purple;
+	-fx-text-fill: white;
 }
 
 
 .link-button {
-    -fx-background-color: transparent;
-    -fx-border-radius: 3;
-    -fx-text-fill: #0096FF;
-    -fx-underline: true;
-    -fx-cursor: hand;
+	-fx-background-color: transparent;
+	-fx-border-radius: 3;
+	-fx-text-fill: #0096FF;
+	-fx-underline: true;
+	-fx-cursor: hand;
 }
 
 .link-button:armed,
 .link-button:focused {
-    -fx-border-color: #006BFF;
-    -fx-text-fill: #006BFF;
+	-fx-border-color: #006BFF;
+	-fx-text-fill: #006BFF;
 }
 
 .link-button .mfx-ripple-generator {
-    -mfx-ripple-color: #D9E9FF;
+	-mfx-ripple-color: #D9E9FF;
 }

+ 3 - 3
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/ChecksRadiosToggles.css

@@ -26,8 +26,8 @@
 }
 
 #customCheck:indeterminate .box .mark {
-	-mfx-description:  "mfx-hyphen";
-} 
+	-mfx-description: "mfx-hyphen";
+}
 
 #customCheck .mfx-ripple-generator {
 	-mfx-ripple-color: -common-gradient;
@@ -121,7 +121,7 @@
 **************************************************/
 .mfx-button {
 	-fx-font-family: 'Visby Round CF Medium';
-    -fx-text-fill: -mfx-text-he;
+	-fx-text-fill: -mfx-text-he;
 }
 
 .mfx-button .text {

+ 2 - 2
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/ComboBoxes.css

@@ -61,8 +61,8 @@
 
 #customNCombo2 .virtual-flow {
 	-track-color: derive(#ff5d53, 90%);
-    -thumb-color: derive(#ff5d53, 50%);
-    -thumb-hover-color: derive(#ff5d53, 25%);
+	-thumb-color: derive(#ff5d53, 50%);
+	-thumb-hover-color: derive(#ff5d53, 25%);
 }
 
 #customNCombo2 .virtual-flow .mfx-combo-box-cell:hover {

+ 11 - 11
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Common.css

@@ -2,30 +2,30 @@
 @import 'MFXColors.css';
 
 .header-label {
-    -fx-font-family: 'Visby Round CF Bold';
-    -fx-font-size: 14;
-    -fx-text-fill: -mfx-text-he;
+	-fx-font-family: 'Visby Round CF Bold';
+	-fx-font-size: 14;
+	-fx-text-fill: -mfx-text-he;
 }
 
 .header-label .text {
-    -fx-font-smoothing-type: lcd;
+	-fx-font-smoothing-type: lcd;
 }
 
 .sub-header-label {
-    -fx-font-family: 'Visby Round CF Demi Bold';
-    -fx-text-fill: -mfx-text-he;
+	-fx-font-family: 'Visby Round CF Demi Bold';
+	-fx-text-fill: -mfx-text-he;
 }
 
 .sub-header-label .text {
-    -fx-font-smoothing-type: lcd;
+	-fx-font-smoothing-type: lcd;
 }
 
 .grid-pane {
-    -fx-background-color: transparent;
+	-fx-background-color: transparent;
 }
 
 .grid-background {
-    -fx-background-color: white;
-    -fx-background-radius: 10;
-    -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.2), 10, 0.12, -1.0, 2.0);
+	-fx-background-color: white;
+	-fx-background-radius: 10;
+	-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.2), 10, 0.12, -1.0, 2.0);
 }

+ 43 - 43
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Demo.css

@@ -5,40 +5,40 @@
  * Root
 **************************************************/
 .rootPane {
-    -fx-background-color: white;
-    -fx-background-radius: 10;
-    -fx-border-color: #ebebeb;
-    -fx-border-radius: 10;
+	-fx-background-color: white;
+	-fx-background-radius: 10;
+	-fx-border-color: #ebebeb;
+	-fx-border-radius: 10;
 }
 
 /**************************************************
  * Window Header
 **************************************************/
 .rootPane .close-icon {
-    -mfx-color: -mfx-red;
-    -fx-opacity: 0.5;
+	-mfx-color: -mfx-red;
+	-fx-opacity: 0.5;
 }
 
 .rootPane .close-icon:hover {
-    -fx-opacity: 1.0;
+	-fx-opacity: 1.0;
 }
 
 .rootPane .minimize-icon {
-    -mfx-color: #ffbf37;
-    -fx-opacity: 0.5;
+	-mfx-color: #ffbf37;
+	-fx-opacity: 0.5;
 }
 
 .rootPane .minimize-icon:hover {
-    -fx-opacity: 1.0;
+	-fx-opacity: 1.0;
 }
 
 .rootPane .always-on-top-icon {
-    -mfx-color: -mfx-purple;
-    -fx-opacity: 0.5;
+	-mfx-color: -mfx-purple;
+	-fx-opacity: 0.5;
 }
 
 .rootPane .always-on-top-icon:hover {
-    -fx-opacity: 1.0;
+	-fx-opacity: 1.0;
 }
 
 .rootPane .always-on-top-icon:always-on-top {
@@ -49,66 +49,66 @@
  * Sidebar
 **************************************************/
 .rootPane .sidebar {
-    -fx-background-color: -mfx-purple;
-    -fx-background-insets: -1 -5 -1 -1;
-    -fx-background-radius: 0 20 20 0;
+	-fx-background-color: -mfx-purple;
+	-fx-background-insets: -1 -5 -1 -1;
+	-fx-background-radius: 0 20 20 0;
 }
 
 .rootPane .sidebar .header {
-    -fx-font-family: 'Visby Round CF Heavy';
-    -fx-font-size: 24;
-    -fx-text-fill: white;
+	-fx-font-family: 'Visby Round CF Heavy';
+	-fx-font-size: 24;
+	-fx-text-fill: white;
 }
 
 .rootPane .sidebar .header .mfx-font-icon {
-    -mfx-color: white;
+	-mfx-color: white;
 }
 
 .rootPane .sidebar .mfx-scroll-pane {
-    -fx-background-color: transparent;
+	-fx-background-color: transparent;
 
-    -track-color: rgba(255, 255, 255, 0.3);
-    -thumb-color: white;
-    -thumb-hover-color: white;
+	-track-color: rgba(255, 255, 255, 0.3);
+	-thumb-color: white;
+	-thumb-hover-color: white;
 }
 
 .rootPane .sidebar .menu-label {
-    -fx-font-family: 'Visby Round CF Bold';
-    -fx-font-size: 14;
-    -fx-text-fill: white;
+	-fx-font-family: 'Visby Round CF Bold';
+	-fx-font-size: 14;
+	-fx-text-fill: white;
 }
 
 .rootPane .sidebar .navbar .mfx-rectangle-toggle-node {
-    -fx-background-color: transparent;
-    -fx-background-radius: 0;
-    -fx-border-color: transparent;
-    -fx-border-radius: 0;
-    -fx-pref-height: 40;
+	-fx-background-color: transparent;
+	-fx-background-radius: 0;
+	-fx-border-color: transparent;
+	-fx-border-radius: 0;
+	-fx-pref-height: 40;
 
-    -fx-font-family: 'Visby Round CF Demi Bold';
-    -fx-font-size: 13;
-    -fx-text-fill: white;
+	-fx-font-family: 'Visby Round CF Demi Bold';
+	-fx-font-size: 13;
+	-fx-text-fill: white;
 }
 
 .rootPane .sidebar .navbar .mfx-rectangle-toggle-node .mfx-ripple-generator {
-    -mfx-paused: true;
+	-mfx-paused: true;
 }
 
 .rootPane .sidebar .navbar .mfx-rectangle-toggle-node .mfx-icon-wrapper .mfx-font-icon {
-    -mfx-color: white;
+	-mfx-color: white;
 }
 
 .rootPane .sidebar .navbar .mfx-rectangle-toggle-node:selected {
-    -fx-background-color: white;
-    -fx-background-radius: 5;
-    -fx-text-fill: #601cbe;
+	-fx-background-color: white;
+	-fx-background-radius: 5;
+	-fx-text-fill: #601cbe;
 }
 
 .rootPane .sidebar .navbar .mfx-rectangle-toggle-node:selected .selection-rectangle {
-    -fx-stroke: transparent;
-    -fx-fill: #601cbe;
+	-fx-stroke: transparent;
+	-fx-fill: #601cbe;
 }
 
 .rootPane .sidebar .navbar .mfx-rectangle-toggle-node:selected .mfx-icon-wrapper .mfx-font-icon {
-    -mfx-color: #601cbe;
+	-mfx-color: #601cbe;
 }

+ 2 - 2
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/MFXColors.css

@@ -31,6 +31,6 @@
 	-mfx-text-me: rgba(0, 0, 0, 0.60); /* Medium Emphasis*/
 	-mfx-text-disabled: rgba(0, 0, 0, 0.38); /* Disabled */
 
-    -common-gradient: linear-gradient(to right bottom, #c4008b, #d00085, #dc007f, #e60b79, #ef1872, #f5276b, #fa3564, #fe415e, #ff5158, #ff5f52, #ff6c4e, #ff794b);
-    -secondary-gradient: linear-gradient(to right bottom, #1ec400, #00bd3a, #00b654, #00ae67, #00a574, #00a280, #009e8a, #009a91, #009b9d, #009ba8, #009bb2, #009abb);
+	-common-gradient: linear-gradient(to right bottom, #c4008b, #d00085, #dc007f, #e60b79, #ef1872, #f5276b, #fa3564, #fe415e, #ff5158, #ff5f52, #ff6c4e, #ff794b);
+	-secondary-gradient: linear-gradient(to right bottom, #1ec400, #00bd3a, #00b654, #00ae67, #00a574, #00a280, #009e8a, #009a91, #009b9d, #009ba8, #009bb2, #009abb);
 }

+ 2 - 2
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Pickers.css

@@ -66,8 +66,8 @@
 #custDatePicker .date-picker-popup .months-combo .virtual-flow,
 #custDatePicker .date-picker-popup .years-combo .virtual-flow {
 	-track-color: derive(#007BF6, 100%);
-    -thumb-color: derive(#007BF6, 70%);
-    -thumb-hover-color: derive(#007BF6, 45%);
+	-thumb-color: derive(#007BF6, 70%);
+	-thumb-hover-color: derive(#007BF6, 45%);
 }
 
 #custDatePicker .date-picker-popup .months-combo .virtual-flow .mfx-combo-box-cell,

+ 9 - 9
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Progress.css

@@ -27,27 +27,27 @@
 }
 
 #determinateBar:range1 .bar1 {
-    -fx-fill: -mfx-red;
+	-fx-fill: -mfx-red;
 }
 
 #determinateBar:range1 .track {
-    -fx-fill: derive(-mfx-red, 85%)
+	-fx-fill: derive(-mfx-red, 85%)
 }
 
 #determinateBar:range2 .bar1 {
-    -fx-fill: -mfx-blue;
+	-fx-fill: -mfx-blue;
 }
 
 #determinateBar:range2 .track {
-    -fx-fill: derive(-mfx-blue, 85%)
+	-fx-fill: derive(-mfx-blue, 85%)
 }
 
 #determinateBar:range3 .bar1 {
-    -fx-fill: -mfx-green;
+	-fx-fill: -mfx-green;
 }
 
 #determinateBar:range3 .track {
-    -fx-fill: derive(-mfx-green, 85%);
+	-fx-fill: derive(-mfx-green, 85%);
 }
 
 
@@ -72,13 +72,13 @@
 }
 
 #determinateSpinner:range1 .arc {
-    -fx-fill: #FF6088;
+	-fx-fill: #FF6088;
 }
 
 #determinateSpinner:range2 .arc {
-    -fx-fill: #00BCFF;
+	-fx-fill: #00BCFF;
 }
 
 #determinateSpinner:range3 .arc {
-    -fx-fill: #1EC400;
+	-fx-fill: #1EC400;
 }

+ 18 - 18
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Sliders.css

@@ -4,60 +4,60 @@
 
 #customSlider:range1 .thumb,
 #customSlider:range1 .track {
-    -mfx-color: -mfx-red;
-    -fx-fill: derive(-mfx-red, 85%)
+	-mfx-color: -mfx-red;
+	-fx-fill: derive(-mfx-red, 85%)
 }
 
 #customSlider:range1 .bar {
-    -fx-fill: -mfx-red;
+	-fx-fill: -mfx-red;
 }
 
 #customSlider:range2 .thumb,
 #customSlider:range2 .track {
-    -mfx-color: -mfx-blue;
-    -fx-fill: derive(-mfx-blue, 85%)
+	-mfx-color: -mfx-blue;
+	-fx-fill: derive(-mfx-blue, 85%)
 }
 
 #customSlider:range2 .bar {
-    -fx-fill: -mfx-blue;
+	-fx-fill: -mfx-blue;
 }
 
 #customSlider:range3 .bar,
 #customSlider:range3 .thumb {
-    -mfx-color: -mfx-green;
-    -fx-fill: -mfx-green;
+	-mfx-color: -mfx-green;
+	-fx-fill: -mfx-green;
 }
 
 #customSlider:range3 .track {
-    -fx-fill: derive(-mfx-green, 85%);
+	-fx-fill: derive(-mfx-green, 85%);
 }
 
 #customSlider:range1 .thumb-container:hover .thumb-radius,
 #customSlider:range1 .thumb-container:pressed .thumb-radius {
-    -mfx-color: derive(-mfx-red, 85%);
-    -fx-opacity: 0.5;
+	-mfx-color: derive(-mfx-red, 85%);
+	-fx-opacity: 0.5;
 }
 
 #customSlider:range2 .thumb-container:hover .thumb-radius,
 #customSlider:range2 .thumb-container:pressed .thumb-radius {
-    -mfx-color: derive(-mfx-blue, 85%);
-    -fx-opacity: 0.5;
+	-mfx-color: derive(-mfx-blue, 85%);
+	-fx-opacity: 0.5;
 }
 
 #customSlider:range3 .thumb-container:hover .thumb-radius,
 #customSlider:range3 .thumb-container:pressed .thumb-radius {
-    -mfx-color: derive(-mfx-green, 70%);
-    -fx-opacity: 0.5;
+	-mfx-color: derive(-mfx-green, 70%);
+	-fx-opacity: 0.5;
 }
 
 #customSlider:range1 .thumb-container .mfx-ripple-generator {
-    -mfx-ripple-color: -mfx-red;
+	-mfx-ripple-color: -mfx-red;
 }
 
 #customSlider:range2 .thumb-container .mfx-ripple-generator {
-    -mfx-ripple-color: -mfx-blue;
+	-mfx-ripple-color: -mfx-blue;
 }
 
 #customSlider:range3 .thumb-container .mfx-ripple-generator {
-    -mfx-ripple-color: -mfx-green;
+	-mfx-ripple-color: -mfx-green;
 }

+ 6 - 6
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/Stepper.css

@@ -33,15 +33,15 @@
 }
 
 .outline-button {
-    -fx-background-color: transparent;
-    -fx-border-color: -mfx-purple;
-    -fx-border-radius: 3;
+	-fx-background-color: transparent;
+	-fx-border-color: -mfx-purple;
+	-fx-border-radius: 3;
 
-    -fx-text-fill: -mfx-purple;
+	-fx-text-fill: -mfx-purple;
 }
 
 .outline-button:hover,
 .outline-button:focused {
-    -fx-background-color: -mfx-purple;
-    -fx-text-fill: white;
+	-fx-background-color: -mfx-purple;
+	-fx-text-fill: white;
 }

+ 10 - 10
demo/src/main/resources/io/github/palexdev/materialfx/demo/css/TextFields.css

@@ -7,27 +7,27 @@
 **************************************************/
 .mfx-text-field {
 	-fx-min-width: 130;
-    -fx-font-family: 'Visby Round CF Medium';
+	-fx-font-family: 'Visby Round CF Medium';
 }
 
 .mfx-text-field .floating-text {
-    -fx-font-family: 'Visby Round CF Medium';
+	-fx-font-family: 'Visby Round CF Medium';
 }
 
 
 #customField {
-    -fx-border-color: -common-gradient;
+	-fx-border-color: -common-gradient;
 }
 
 #customField .floating-text {
-    -fx-text-fill: -mfx-red;
+	-fx-text-fill: -mfx-red;
 }
 
 /**************************************************
  * Password Fields
 **************************************************/
 #customPassword {
-    -fx-border-color: -secondary-gradient;
+	-fx-border-color: -secondary-gradient;
 }
 
 #customPassword:masked {
@@ -51,18 +51,18 @@
 }
 
 #validatedField:invalid {
-    -fx-border-color: -mfx-red;
+	-fx-border-color: -mfx-red;
 }
 
 #validatedField:invalid .floating-text {
-    -fx-text-fill: -mfx-red;
+	-fx-text-fill: -mfx-red;
 }
 
 #validatedField:invalid .mfx-font-icon {
-    -mfx-color: -mfx-red;
+	-mfx-color: -mfx-red;
 }
 
 #validationLabel {
-    -fx-font-family: 'Visby Round CF Demi Bold';
-    -fx-font-size: 11;
+	-fx-font-family: 'Visby Round CF Demi Bold';
+	-fx-font-size: 11;
 }

+ 179 - 179
demo/src/main/resources/io/github/palexdev/materialfx/demo/fonts/Fonts.css

@@ -1,286 +1,286 @@
 @font-face {
-    font-family: 'Comfortaa Bold';
-    font-weight: bold;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Comfortaa/Comfortaa-Bold.ttf') format('truetype');
+	font-family: 'Comfortaa Bold';
+	font-weight: bold;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Comfortaa/Comfortaa-Bold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Comfortaa Light';
-    font-weight: 300px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Comfortaa/Comfortaa-Light.ttf') format('truetype');
+	font-family: 'Comfortaa Light';
+	font-weight: 300px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Comfortaa/Comfortaa-Light.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Comfortaa Medium';
-    font-weight: 500px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Comfortaa/Comfortaa-Medium.ttf') format('truetype');
+	font-family: 'Comfortaa Medium';
+	font-weight: 500px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Comfortaa/Comfortaa-Medium.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Comfortaa Regular';
-    font-weight: normal;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Comfortaa/Comfortaa-Regular.ttf') format('truetype');
+	font-family: 'Comfortaa Regular';
+	font-weight: normal;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Comfortaa/Comfortaa-Regular.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Comfortaa SemiBold';
-    font-weight: 600px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Comfortaa/Comfortaa-SemiBold.ttf') format('truetype');
+	font-family: 'Comfortaa SemiBold';
+	font-weight: 600px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Comfortaa/Comfortaa-SemiBold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans Bold';
-    font-weight: bold;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-Bold.ttf') format('truetype');
+	font-family: 'Open Sans Bold';
+	font-weight: bold;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-Bold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans BoldItalic';
-    font-weight: bold;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-BoldItalic.ttf') format('truetype');
+	font-family: 'Open Sans BoldItalic';
+	font-weight: bold;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-BoldItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans ExtraBold';
-    font-weight: 800px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-ExtraBold.ttf') format('truetype');
+	font-family: 'Open Sans ExtraBold';
+	font-weight: 800px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-ExtraBold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans ExtraBoldItalic';
-    font-weight: 800px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf') format('truetype');
+	font-family: 'Open Sans ExtraBoldItalic';
+	font-weight: 800px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans Light';
-    font-weight: 300px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-Light.ttf') format('truetype');
+	font-family: 'Open Sans Light';
+	font-weight: 300px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-Light.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans LightItalic';
-    font-weight: 300px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-LightItalic.ttf') format('truetype');
+	font-family: 'Open Sans LightItalic';
+	font-weight: 300px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-LightItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans Italic';
-    font-weight: normal;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-Italic.ttf') format('truetype');
+	font-family: 'Open Sans Italic';
+	font-weight: normal;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-Italic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans SemiBold';
-    font-weight: 600px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-SemiBold.ttf') format('truetype');
+	font-family: 'Open Sans SemiBold';
+	font-weight: 600px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-SemiBold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans Regular';
-    font-weight: normal;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-Regular.ttf') format('truetype');
+	font-family: 'Open Sans Regular';
+	font-weight: normal;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-Regular.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Open Sans SemiBoldItalic';
-    font-weight: 600px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/OpenSans/OpenSans-SemiBoldItalic.ttf') format('truetype');
+	font-family: 'Open Sans SemiBoldItalic';
+	font-weight: 600px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/OpenSans/OpenSans-SemiBoldItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Black';
-    font-weight: 900px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Black.ttf') format('truetype');
+	font-family: 'Roboto Black';
+	font-weight: 900px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Black.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto BlackItalic';
-    font-weight: 900px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-BlackItalic.ttf') format('truetype');
+	font-family: 'Roboto BlackItalic';
+	font-weight: 900px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-BlackItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Bold';
-    font-weight: bold;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Bold.ttf') format('truetype');
+	font-family: 'Roboto Bold';
+	font-weight: bold;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Bold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto BoldItalic';
-    font-weight: bold;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-BoldItalic.ttf') format('truetype');
+	font-family: 'Roboto BoldItalic';
+	font-weight: bold;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-BoldItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Light';
-    font-weight: 300px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Light.ttf') format('truetype');
+	font-family: 'Roboto Light';
+	font-weight: 300px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Light.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Italic';
-    font-weight: normal;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Italic.ttf') format('truetype');
+	font-family: 'Roboto Italic';
+	font-weight: normal;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Italic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto LightItalic';
-    font-weight: 300px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-LightItalic.ttf') format('truetype');
+	font-family: 'Roboto LightItalic';
+	font-weight: 300px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-LightItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Medium';
-    font-weight: 500px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Medium.ttf') format('truetype');
+	font-family: 'Roboto Medium';
+	font-weight: 500px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Medium.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto MediumItalic';
-    font-weight: 500px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-MediumItalic.ttf') format('truetype');
+	font-family: 'Roboto MediumItalic';
+	font-weight: 500px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-MediumItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Regular';
-    font-weight: normal;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Regular.ttf') format('truetype');
+	font-family: 'Roboto Regular';
+	font-weight: normal;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Regular.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto ThinItalic';
-    font-weight: 100px;
-    font-style: italic;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-ThinItalic.ttf') format('truetype');
+	font-family: 'Roboto ThinItalic';
+	font-weight: 100px;
+	font-style: italic;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-ThinItalic.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Roboto Thin';
-    font-weight: 100px;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Roboto/Roboto-Thin.ttf') format('truetype');
+	font-family: 'Roboto Thin';
+	font-weight: 100px;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Roboto/Roboto-Thin.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Varela Round';
-    font-weight: normal;
-    font-display: swap;
-    src: url('../fonts/Varela/VarelaRound-Regular.ttf') format('truetype');
+	font-family: 'Varela Round';
+	font-weight: normal;
+	font-display: swap;
+	src: url('../fonts/Varela/VarelaRound-Regular.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF Demi';
-    font-weight: 600;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-DemiBold.ttf') format('truetype');
+	font-family: 'Visby Round CF Demi';
+	font-weight: 600;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-DemiBold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF Extra';
-    font-weight: bold;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-ExtraBold.ttf') format('truetype');
+	font-family: 'Visby Round CF Extra';
+	font-weight: bold;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-ExtraBold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF';
-    font-weight: bold;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-Bold.ttf') format('truetype');
+	font-family: 'Visby Round CF';
+	font-weight: bold;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-Bold.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF';
-    font-weight: 900;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-Heavy.ttf') format('truetype');
+	font-family: 'Visby Round CF';
+	font-weight: 900;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-Heavy.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF Extra';
-    font-weight: 200;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-ExtraLight.ttf') format('truetype');
+	font-family: 'Visby Round CF Extra';
+	font-weight: 200;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-ExtraLight.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF';
-    font-weight: 300;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-Light.ttf') format('truetype');
+	font-family: 'Visby Round CF';
+	font-weight: 300;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-Light.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF';
-    font-weight: 500;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-Medium.ttf') format('truetype');
+	font-family: 'Visby Round CF';
+	font-weight: 500;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-Medium.ttf') format('truetype');
 }
 
 @font-face {
-    font-family: 'Visby Round CF';
-    font-weight: normal;
-    font-style: normal;
-    font-display: swap;
-    src: url('../fonts/Visby/VisbyRoundCF-Regular.ttf') format('truetype');
+	font-family: 'Visby Round CF';
+	font-weight: normal;
+	font-style: normal;
+	font-display: swap;
+	src: url('../fonts/Visby/VisbyRoundCF-Regular.ttf') format('truetype');
 }

+ 6 - 6
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Buttons.fxml

@@ -28,10 +28,10 @@
     <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
                GridPane.rowSpan="2">
         <GridPane.margin>
-          <Insets left="-15.0" right="-15.0"/>
+            <Insets left="-15.0" right="-15.0"/>
         </GridPane.margin>
         <opaqueInsets>
-          <Insets/>
+            <Insets/>
         </opaqueInsets>
     </StackPane>
     <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Flat Buttons"
@@ -44,10 +44,10 @@
     <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
                GridPane.rowIndex="3" GridPane.rowSpan="2">
         <opaqueInsets>
-          <Insets/>
+            <Insets/>
         </opaqueInsets>
         <GridPane.margin>
-          <Insets left="-15.0" right="-15.0"/>
+            <Insets left="-15.0" right="-15.0"/>
         </GridPane.margin>
     </StackPane>
     <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
@@ -60,7 +60,7 @@
     <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
                GridPane.columnSpan="3" GridPane.rowSpan="2">
         <GridPane.margin>
-          <Insets left="-15.0" right="-15.0"/>
+            <Insets left="-15.0" right="-15.0"/>
         </GridPane.margin>
     </StackPane>
     <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Outlined Buttons"
@@ -74,7 +74,7 @@
     <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
                GridPane.columnSpan="3" GridPane.rowIndex="3" GridPane.rowSpan="2">
         <GridPane.margin>
-          <Insets left="-15.0" right="-15.0"/>
+            <Insets left="-15.0" right="-15.0"/>
         </GridPane.margin>
     </StackPane>
     <Label styleClass="header-label" text="Other Buttons" GridPane.columnIndex="5" GridPane.rowIndex="3"/>

+ 102 - 102
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ChecksRadiosToggles.fxml

@@ -8,106 +8,106 @@
 <GridPane alignment="CENTER" hgap="20.0" styleClass="grid-pane" stylesheets="@../css/ChecksRadiosToggles.css"
           vgap="20.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.ChecksRadiosToggleController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
-      <ColumnConstraints halignment="CENTER" prefWidth="150.0"/>
-      <ColumnConstraints halignment="CENTER" prefWidth="150.0"/>
-      <ColumnConstraints halignment="CENTER" prefWidth="150.0"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="20.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Checkboxes"
-          GridPane.columnSpan="3"/>
-   <MFXCheckbox allowIndeterminate="true" text="Checkbox" GridPane.rowIndex="1"/>
-   <MFXCheckbox id="customCheck" allowIndeterminate="true" text="Custom" GridPane.columnIndex="1"
-                GridPane.rowIndex="1"/>
-   <MFXCheckbox id="customCheck" allowIndeterminate="true" contentDisposition="TOP" gap="5.0" text="Custom"
-                GridPane.columnIndex="2" GridPane.rowIndex="1"/>
-   <MFXCheckbox disable="true" text="Disabled" GridPane.rowIndex="2"/>
-   <MFXCheckbox disable="true" selected="true" text="Disabled" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
-   <MFXCheckbox allowIndeterminate="true" disable="true" indeterminate="true" text="Disabled" GridPane.columnIndex="2"
-                GridPane.rowIndex="2"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowIndex="4" GridPane.rowSpan="3">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Radio Buttons" GridPane.columnSpan="3" GridPane.rowIndex="4"/>
-   <MFXRadioButton text="Radio" GridPane.rowIndex="5"/>
-   <MFXRadioButton id="customRadio" text="Custom" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
-   <MFXRadioButton id="customRadio" contentDisposition="TOP" gap="5.0" radioGap="5.0" radius="10.0" text="Custom"
-                   GridPane.columnIndex="2" GridPane.rowIndex="5"/>
-   <MFXRadioButton disable="true" text="Disabled" GridPane.rowIndex="6"/>
-   <MFXRadioButton disable="true" selected="true" text="Disabled" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
-              GridPane.columnSpan="3" GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Toggle Buttons"
-          GridPane.columnIndex="4" GridPane.columnSpan="3"/>
-   <MFXToggleButton text="Switch" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
-   <MFXToggleButton id="customToggleButton" text="Custom" GridPane.columnIndex="5" GridPane.rowIndex="1"/>
-   <MFXToggleButton id="customToggleButton" fx:id="customToggle" contentDisposition="TOP" gap="5.0" length="50.0"
-                    radius="12.0" text="Custom" GridPane.columnIndex="6" GridPane.rowIndex="1"/>
-   <MFXToggleButton disable="true" text="Disabled" GridPane.columnIndex="4" GridPane.rowIndex="2"/>
-   <MFXToggleButton disable="true" selected="true" text="Disabled" GridPane.columnIndex="5" GridPane.rowIndex="2"/>
-   <MFXButton buttonType="RAISED" depthLevel="LEVEL1" minHeight="27.0" onAction="#changeColors" text="Random Colors"
-              GridPane.columnIndex="6" GridPane.rowIndex="2"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
-              GridPane.columnSpan="3" GridPane.rowIndex="4" GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label styleClass="header-label" text="Toggle Nodes" GridPane.columnIndex="5" GridPane.rowIndex="4"/>
-   <MFXCircleToggleNode text="Circle Toggle" GridPane.columnIndex="4" GridPane.rowIndex="5">
-      <graphic>
-         <MFXFontIcon description="mfx-bell" size="32.0"/>
-      </graphic>
-   </MFXCircleToggleNode>
-   <MFXCircleToggleNode id="customCircle" text="Custom" textPosition="TOP" GridPane.columnIndex="5"
-                        GridPane.rowIndex="5">
-      <graphic>
-         <MFXFontIcon description="mfx-gear" size="32.0"/>
-      </graphic>
-   </MFXCircleToggleNode>
-   <MFXCircleToggleNode disable="true" selected="true" text="Disabled" GridPane.columnIndex="6" GridPane.rowIndex="5">
-      <graphic>
-         <MFXFontIcon description="mfx-eye" size="32.0"/>
-      </graphic>
-   </MFXCircleToggleNode>
-   <MFXRectangleToggleNode fx:id="r1" text="Rectangle Toggle" GridPane.columnIndex="4" GridPane.rowIndex="6"/>
-   <MFXRectangleToggleNode id="customRectangle" fx:id="r2" text="Custom" GridPane.columnIndex="5"
-                           GridPane.rowIndex="6"/>
-   <MFXRectangleToggleNode fx:id="r3" disable="true" selected="true" text="Disabled" GridPane.columnIndex="6"
-                           GridPane.rowIndex="6"/>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
+        <ColumnConstraints halignment="CENTER" prefWidth="150.0"/>
+        <ColumnConstraints halignment="CENTER" prefWidth="150.0"/>
+        <ColumnConstraints halignment="CENTER" prefWidth="150.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="20.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Checkboxes"
+           GridPane.columnSpan="3"/>
+    <MFXCheckbox allowIndeterminate="true" text="Checkbox" GridPane.rowIndex="1"/>
+    <MFXCheckbox id="customCheck" allowIndeterminate="true" text="Custom" GridPane.columnIndex="1"
+                 GridPane.rowIndex="1"/>
+    <MFXCheckbox id="customCheck" allowIndeterminate="true" contentDisposition="TOP" gap="5.0" text="Custom"
+                 GridPane.columnIndex="2" GridPane.rowIndex="1"/>
+    <MFXCheckbox disable="true" text="Disabled" GridPane.rowIndex="2"/>
+    <MFXCheckbox disable="true" selected="true" text="Disabled" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
+    <MFXCheckbox allowIndeterminate="true" disable="true" indeterminate="true" text="Disabled" GridPane.columnIndex="2"
+                 GridPane.rowIndex="2"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowIndex="4" GridPane.rowSpan="3">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Radio Buttons" GridPane.columnSpan="3" GridPane.rowIndex="4"/>
+    <MFXRadioButton text="Radio" GridPane.rowIndex="5"/>
+    <MFXRadioButton id="customRadio" text="Custom" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
+    <MFXRadioButton id="customRadio" contentDisposition="TOP" gap="5.0" radioGap="5.0" radius="10.0" text="Custom"
+                    GridPane.columnIndex="2" GridPane.rowIndex="5"/>
+    <MFXRadioButton disable="true" text="Disabled" GridPane.rowIndex="6"/>
+    <MFXRadioButton disable="true" selected="true" text="Disabled" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
+               GridPane.columnSpan="3" GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Toggle Buttons"
+           GridPane.columnIndex="4" GridPane.columnSpan="3"/>
+    <MFXToggleButton text="Switch" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
+    <MFXToggleButton id="customToggleButton" text="Custom" GridPane.columnIndex="5" GridPane.rowIndex="1"/>
+    <MFXToggleButton id="customToggleButton" fx:id="customToggle" contentDisposition="TOP" gap="5.0" length="50.0"
+                     radius="12.0" text="Custom" GridPane.columnIndex="6" GridPane.rowIndex="1"/>
+    <MFXToggleButton disable="true" text="Disabled" GridPane.columnIndex="4" GridPane.rowIndex="2"/>
+    <MFXToggleButton disable="true" selected="true" text="Disabled" GridPane.columnIndex="5" GridPane.rowIndex="2"/>
+    <MFXButton buttonType="RAISED" depthLevel="LEVEL1" minHeight="27.0" onAction="#changeColors" text="Random Colors"
+               GridPane.columnIndex="6" GridPane.rowIndex="2"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
+               GridPane.columnSpan="3" GridPane.rowIndex="4" GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label styleClass="header-label" text="Toggle Nodes" GridPane.columnIndex="5" GridPane.rowIndex="4"/>
+    <MFXCircleToggleNode text="Circle Toggle" GridPane.columnIndex="4" GridPane.rowIndex="5">
+        <graphic>
+            <MFXFontIcon description="mfx-bell" size="32.0"/>
+        </graphic>
+    </MFXCircleToggleNode>
+    <MFXCircleToggleNode id="customCircle" text="Custom" textPosition="TOP" GridPane.columnIndex="5"
+                         GridPane.rowIndex="5">
+        <graphic>
+            <MFXFontIcon description="mfx-gear" size="32.0"/>
+        </graphic>
+    </MFXCircleToggleNode>
+    <MFXCircleToggleNode disable="true" selected="true" text="Disabled" GridPane.columnIndex="6" GridPane.rowIndex="5">
+        <graphic>
+            <MFXFontIcon description="mfx-eye" size="32.0"/>
+        </graphic>
+    </MFXCircleToggleNode>
+    <MFXRectangleToggleNode fx:id="r1" text="Rectangle Toggle" GridPane.columnIndex="4" GridPane.rowIndex="6"/>
+    <MFXRectangleToggleNode id="customRectangle" fx:id="r2" text="Custom" GridPane.columnIndex="5"
+                            GridPane.rowIndex="6"/>
+    <MFXRectangleToggleNode fx:id="r3" disable="true" selected="true" text="Disabled" GridPane.columnIndex="6"
+                            GridPane.rowIndex="6"/>
 </GridPane>

+ 69 - 69
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ComboBoxes.fxml

@@ -8,73 +8,73 @@
 <GridPane alignment="CENTER" hgap="20.0" styleClass="grid-pane" stylesheets="@../css/ComboBoxes.css" vgap="20.0"
           xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.ComboBoxesController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="10.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowSpan="3">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="New Combos" GridPane.columnSpan="3"/>
-   <MFXComboBox fx:id="nCombo" floatingText="Combo" GridPane.rowIndex="1"/>
-   <MFXComboBox id="customNCombo" fx:id="nCustCombo" floatingText="Custom" GridPane.columnIndex="1"
-                GridPane.rowIndex="1"/>
-   <MFXComboBox fx:id="nEditCombo" allowEdit="true" floatingText="Editable" scrollOnOpen="true" selectable="true"
-                GridPane.columnIndex="2" GridPane.rowIndex="1"/>
-   <MFXComboBox fx:id="nBFCombo" floatMode="BORDER" floatingText="Border Float" GridPane.rowIndex="2"/>
-   <MFXComboBox id="customNCombo2" fx:id="nNFCombo" floatMode="DISABLED" promptText="No Float Custom"
-                GridPane.columnIndex="1" GridPane.rowIndex="2"/>
-   <MFXComboBox disable="true" floatMode="DISABLED" promptText="Disabled" GridPane.columnIndex="2"
-                GridPane.rowIndex="2"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowIndex="4" GridPane.rowSpan="2">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Legacy Combos"
-          GridPane.columnSpan="3" GridPane.rowIndex="4"/>
-   <MFXLegacyComboBox fx:id="lCombo" promptText="Combo" GridPane.rowIndex="5"/>
-   <MFXLegacyComboBox id="customLCombo" fx:id="lCustCombo" promptText="Custom" GridPane.columnIndex="1"
-                      GridPane.rowIndex="5"/>
-   <MFXLegacyComboBox disable="true" promptText="Disabled" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
-              GridPane.columnSpan="2" GridPane.rowSpan="3">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Filter Combos" GridPane.columnIndex="4" GridPane.columnSpan="2"/>
-   <MFXFilterComboBox fx:id="filterCombo" floatingText="Filter" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
-   <MFXFilterComboBox id="customFilter" fx:id="custFilterCombo" floatMode="DISABLED" promptText="Custom"
-                      GridPane.columnIndex="5" GridPane.rowIndex="1"/>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="10.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowSpan="3">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="New Combos" GridPane.columnSpan="3"/>
+    <MFXComboBox fx:id="nCombo" floatingText="Combo" GridPane.rowIndex="1"/>
+    <MFXComboBox id="customNCombo" fx:id="nCustCombo" floatingText="Custom" GridPane.columnIndex="1"
+                 GridPane.rowIndex="1"/>
+    <MFXComboBox fx:id="nEditCombo" allowEdit="true" floatingText="Editable" scrollOnOpen="true" selectable="true"
+                 GridPane.columnIndex="2" GridPane.rowIndex="1"/>
+    <MFXComboBox fx:id="nBFCombo" floatMode="BORDER" floatingText="Border Float" GridPane.rowIndex="2"/>
+    <MFXComboBox id="customNCombo2" fx:id="nNFCombo" floatMode="DISABLED" promptText="No Float Custom"
+                 GridPane.columnIndex="1" GridPane.rowIndex="2"/>
+    <MFXComboBox disable="true" floatMode="DISABLED" promptText="Disabled" GridPane.columnIndex="2"
+                 GridPane.rowIndex="2"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowIndex="4" GridPane.rowSpan="2">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Legacy Combos"
+           GridPane.columnSpan="3" GridPane.rowIndex="4"/>
+    <MFXLegacyComboBox fx:id="lCombo" promptText="Combo" GridPane.rowIndex="5"/>
+    <MFXLegacyComboBox id="customLCombo" fx:id="lCustCombo" promptText="Custom" GridPane.columnIndex="1"
+                       GridPane.rowIndex="5"/>
+    <MFXLegacyComboBox disable="true" promptText="Disabled" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="4"
+               GridPane.columnSpan="2" GridPane.rowSpan="3">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Filter Combos" GridPane.columnIndex="4" GridPane.columnSpan="2"/>
+    <MFXFilterComboBox fx:id="filterCombo" floatingText="Filter" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
+    <MFXFilterComboBox id="customFilter" fx:id="custFilterCombo" floatMode="DISABLED" promptText="Custom"
+                       GridPane.columnIndex="5" GridPane.rowIndex="1"/>
 </GridPane>

+ 43 - 36
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Demo.fxml

@@ -5,40 +5,47 @@
 <?import javafx.geometry.*?>
 <?import javafx.scene.control.Label?>
 <?import javafx.scene.layout.*?>
-<AnchorPane fx:id="rootPane" prefHeight="720.0" prefWidth="1280.0" styleClass="rootPane" stylesheets="@../css/Demo.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="io.github.palexdev.materialfx.demo.controllers.DemoController">
-   <HBox fx:id="windowHeader" alignment="CENTER_RIGHT" layoutY="6.0" prefHeight="50.0" prefWidth="1281.0" spacing="10.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
-      <padding>
-         <Insets right="10.0" />
-      </padding>
-      <MFXFontIcon fx:id="alwaysOnTopIcon" description="mfx-circle" size="15.0" styleClass="always-on-top-icon" />
-      <MFXFontIcon fx:id="minimizeIcon" description="mfx-circle" size="15.0" styleClass="minimize-icon" />
-      <MFXFontIcon fx:id="closeIcon" description="mfx-circle" size="15.0" styleClass="close-icon" />
-   </HBox>
-   <VBox layoutX="227.0" layoutY="51.0" prefWidth="250.0" styleClass="sidebar" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
-      <padding>
-         <Insets bottom="10.0" left="10.0" top="60.0" />
-      </padding>
-      <Label graphicTextGap="15.0" styleClass="header" text="MaterialFX">
-         <graphic>
-            <MFXFontIcon description="mfx-logo" size="52.0" />
-         </graphic>
-      </Label>
-      <Label styleClass="menu-label" text="Components">
-         <VBox.margin>
-            <Insets left="5.0" top="40.0" />
-         </VBox.margin>
-      </Label>
-      <MFXScrollPane fx:id="scrollPane" fitToWidth="true" hbarPolicy="NEVER" VBox.vgrow="ALWAYS">
-         <VBox.margin>
-            <Insets bottom="10.0" left="5.0" top="15.0" />
-         </VBox.margin>
-         <padding>
-            <Insets right="10.0" />
-         </padding>
-         <content>
-            <VBox fx:id="navBar" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" spacing="5.0" styleClass="navbar" />
-         </content>
-      </MFXScrollPane>
-   </VBox>
-   <StackPane fx:id="contentPane" layoutX="252.0" layoutY="52.0" prefHeight="150.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="252.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="51.0" />
+<AnchorPane fx:id="rootPane" prefHeight="720.0" prefWidth="1280.0" styleClass="rootPane" stylesheets="@../css/Demo.css"
+            xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
+            fx:controller="io.github.palexdev.materialfx.demo.controllers.DemoController">
+    <HBox fx:id="windowHeader" alignment="CENTER_RIGHT" layoutY="6.0" prefHeight="50.0" prefWidth="1281.0"
+          spacing="10.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+        <padding>
+            <Insets right="10.0"/>
+        </padding>
+        <MFXFontIcon fx:id="alwaysOnTopIcon" description="mfx-circle" size="15.0" styleClass="always-on-top-icon"/>
+        <MFXFontIcon fx:id="minimizeIcon" description="mfx-circle" size="15.0" styleClass="minimize-icon"/>
+        <MFXFontIcon fx:id="closeIcon" description="mfx-circle" size="15.0" styleClass="close-icon"/>
+    </HBox>
+    <VBox layoutX="227.0" layoutY="51.0" prefWidth="250.0" styleClass="sidebar" AnchorPane.bottomAnchor="0.0"
+          AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0">
+        <padding>
+            <Insets bottom="10.0" left="10.0" top="60.0"/>
+        </padding>
+        <Label graphicTextGap="15.0" styleClass="header" text="MaterialFX">
+            <graphic>
+                <MFXFontIcon description="mfx-logo" size="52.0"/>
+            </graphic>
+        </Label>
+        <Label styleClass="menu-label" text="Components">
+            <VBox.margin>
+                <Insets left="5.0" top="40.0"/>
+            </VBox.margin>
+        </Label>
+        <MFXScrollPane fx:id="scrollPane" fitToWidth="true" hbarPolicy="NEVER" VBox.vgrow="ALWAYS">
+            <VBox.margin>
+                <Insets bottom="10.0" left="5.0" top="15.0"/>
+            </VBox.margin>
+            <padding>
+                <Insets right="10.0"/>
+            </padding>
+            <content>
+                <VBox fx:id="navBar" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" spacing="5.0"
+                      styleClass="navbar"/>
+            </content>
+        </MFXScrollPane>
+    </VBox>
+    <StackPane fx:id="contentPane" layoutX="252.0" layoutY="52.0" prefHeight="150.0" prefWidth="200.0"
+               AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="252.0" AnchorPane.rightAnchor="10.0"
+               AnchorPane.topAnchor="51.0"/>
 </AnchorPane>

+ 18 - 13
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/FontResources.fxml

@@ -6,17 +6,22 @@
 <?import javafx.scene.effect.DropShadow?>
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.paint.Color?>
-<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="900.0" spacing="10.0" style="-fx-background-color: white; -fx-background-radius: 10;" stylesheets="@../css/Common.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="io.github.palexdev.materialfx.demo.controllers.FontResourcesController">
-   <padding>
-      <Insets bottom="20.0" left="20.0" right="20.0" top="10.0" />
-   </padding>
-   <effect>
-      <DropShadow blurType="GAUSSIAN" offsetX="-1.0" offsetY="2.0" spread="0.12">
-         <color>
-            <Color opacity="0.20000000298023224" />
-         </color>
-      </DropShadow>
-   </effect>
-   <Label fx:id="header" alignment="CENTER" maxWidth="1.7976931348623157E308" minHeight="32.0" styleClass="header-label" text="MaterialFX Font Resources" />
-   <MFXTableView fx:id="tableView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" stylesheets="@../css/FontResources.css" VBox.vgrow="ALWAYS" />
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0"
+      prefWidth="900.0" spacing="10.0" style="-fx-background-color: white; -fx-background-radius: 10;"
+      stylesheets="@../css/Common.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
+      fx:controller="io.github.palexdev.materialfx.demo.controllers.FontResourcesController">
+    <padding>
+        <Insets bottom="20.0" left="20.0" right="20.0" top="10.0"/>
+    </padding>
+    <effect>
+        <DropShadow blurType="GAUSSIAN" offsetX="-1.0" offsetY="2.0" spread="0.12">
+            <color>
+                <Color opacity="0.20000000298023224"/>
+            </color>
+        </DropShadow>
+    </effect>
+    <Label fx:id="header" alignment="CENTER" maxWidth="1.7976931348623157E308" minHeight="32.0"
+           styleClass="header-label" text="MaterialFX Font Resources"/>
+    <MFXTableView fx:id="tableView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+                  stylesheets="@../css/FontResources.css" VBox.vgrow="ALWAYS"/>
 </VBox>

+ 71 - 71
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ListViews.fxml

@@ -8,75 +8,75 @@
           stylesheets="@../css/ListViews.css" vgap="20.0" xmlns="http://javafx.com/javafx/17"
           xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.ListViewsController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowSpan="2147483647">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Lists"
-          GridPane.columnSpan="3"/>
-   <Label styleClass="sub-header-label" text="Default" GridPane.rowIndex="1"/>
-   <MFXListView fx:id="list" prefWidth="170.0" GridPane.rowIndex="2" GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets bottom="15.0"/>
-      </GridPane.margin>
-   </MFXListView>
-   <Label styleClass="sub-header-label" text="Custom" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
-   <MFXListView id="custList" fx:id="custList" prefWidth="170.0" GridPane.columnIndex="1" GridPane.rowIndex="2"
-                GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets bottom="15.0"/>
-      </GridPane.margin>
-   </MFXListView>
-   <Label styleClass="sub-header-label" text="Check List" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
-   <MFXCheckListView fx:id="checkList" prefWidth="170.0" GridPane.columnIndex="2" GridPane.rowIndex="2"
-                     GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets bottom="15.0"/>
-      </GridPane.margin>
-   </MFXCheckListView>
-   <MFXButton minHeight="32.0" onAction="#changeColors" text="Change Scrollbar Colors" GridPane.columnIndex="1"
-              GridPane.rowIndex="5">
-      <GridPane.margin>
-         <Insets bottom="20.0"/>
-      </GridPane.margin>
-   </MFXButton>
-   <StackPane prefHeight="150.0" prefWidth="200.0" styleClass="grid-background" GridPane.columnIndex="4"
-              GridPane.rowSpan="2147483647">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label styleClass="header-label" text="Legacy" GridPane.columnIndex="4"/>
-   <MFXListView fx:id="legacyList" prefWidth="170.0" GridPane.columnIndex="4" GridPane.rowIndex="2"
-                GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets bottom="15.0"/>
-      </GridPane.margin>
-   </MFXListView>
-   <MFXButton minHeight="32.0" onAction="#changeDepth" text="3D/2D" GridPane.columnIndex="1" GridPane.rowIndex="6">
-      <GridPane.margin>
-         <Insets bottom="20.0"/>
-      </GridPane.margin>
-   </MFXButton>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowSpan="2147483647">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Lists"
+           GridPane.columnSpan="3"/>
+    <Label styleClass="sub-header-label" text="Default" GridPane.rowIndex="1"/>
+    <MFXListView fx:id="list" prefWidth="170.0" GridPane.rowIndex="2" GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets bottom="15.0"/>
+        </GridPane.margin>
+    </MFXListView>
+    <Label styleClass="sub-header-label" text="Custom" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
+    <MFXListView id="custList" fx:id="custList" prefWidth="170.0" GridPane.columnIndex="1" GridPane.rowIndex="2"
+                 GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets bottom="15.0"/>
+        </GridPane.margin>
+    </MFXListView>
+    <Label styleClass="sub-header-label" text="Check List" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
+    <MFXCheckListView fx:id="checkList" prefWidth="170.0" GridPane.columnIndex="2" GridPane.rowIndex="2"
+                      GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets bottom="15.0"/>
+        </GridPane.margin>
+    </MFXCheckListView>
+    <MFXButton minHeight="32.0" onAction="#changeColors" text="Change Scrollbar Colors" GridPane.columnIndex="1"
+               GridPane.rowIndex="5">
+        <GridPane.margin>
+            <Insets bottom="20.0"/>
+        </GridPane.margin>
+    </MFXButton>
+    <StackPane prefHeight="150.0" prefWidth="200.0" styleClass="grid-background" GridPane.columnIndex="4"
+               GridPane.rowSpan="2147483647">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label styleClass="header-label" text="Legacy" GridPane.columnIndex="4"/>
+    <MFXListView fx:id="legacyList" prefWidth="170.0" GridPane.columnIndex="4" GridPane.rowIndex="2"
+                 GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets bottom="15.0"/>
+        </GridPane.margin>
+    </MFXListView>
+    <MFXButton minHeight="32.0" onAction="#changeDepth" text="3D/2D" GridPane.columnIndex="1" GridPane.rowIndex="6">
+        <GridPane.margin>
+            <Insets bottom="20.0"/>
+        </GridPane.margin>
+    </MFXButton>
 </GridPane>

+ 57 - 57
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Notifications.fxml

@@ -8,61 +8,61 @@
           stylesheets="@../css/Buttons.css" vgap="20.0" xmlns="http://javafx.com/javafx/17"
           xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.NotificationsController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Notifications"
-          GridPane.columnSpan="3"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopLeft" styleClass="outline-button" text="Show Top Left"
-              GridPane.rowIndex="1"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopCenter" styleClass="outline-button"
-              text="Show Top Center" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopRight" styleClass="outline-button"
-              text="Show Top Right" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomLeft" styleClass="outline-button"
-              text="Show Bottom Left" GridPane.rowIndex="2"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomCenter" styleClass="outline-button"
-              text="Show Bottom Center" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomRight" styleClass="outline-button"
-              text="Show Bottom Right" GridPane.columnIndex="2" GridPane.rowIndex="2"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowIndex="4" GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Notification Center"
-          GridPane.columnSpan="3" GridPane.rowIndex="4"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopLeftNC" styleClass="outline-button"
-              text="Show Top Left" GridPane.rowIndex="5"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopCenterNC" styleClass="outline-button"
-              text="Show Top Center" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopRightNC" styleClass="outline-button"
-              text="Show Top Right" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomLeftNC" styleClass="outline-button"
-              text="Show Bottom Left" GridPane.rowIndex="6"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomCenterNC" styleClass="outline-button"
-              text="Show Bottom Center" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
-   <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomRightNC" styleClass="outline-button"
-              text="Show Bottom Right" GridPane.columnIndex="2" GridPane.rowIndex="6"/>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Notifications"
+           GridPane.columnSpan="3"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopLeft" styleClass="outline-button" text="Show Top Left"
+               GridPane.rowIndex="1"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopCenter" styleClass="outline-button"
+               text="Show Top Center" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopRight" styleClass="outline-button"
+               text="Show Top Right" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomLeft" styleClass="outline-button"
+               text="Show Bottom Left" GridPane.rowIndex="2"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomCenter" styleClass="outline-button"
+               text="Show Bottom Center" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomRight" styleClass="outline-button"
+               text="Show Bottom Right" GridPane.columnIndex="2" GridPane.rowIndex="2"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowIndex="4" GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Notification Center"
+           GridPane.columnSpan="3" GridPane.rowIndex="4"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopLeftNC" styleClass="outline-button"
+               text="Show Top Left" GridPane.rowIndex="5"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopCenterNC" styleClass="outline-button"
+               text="Show Top Center" GridPane.columnIndex="1" GridPane.rowIndex="5"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showTopRightNC" styleClass="outline-button"
+               text="Show Top Right" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomLeftNC" styleClass="outline-button"
+               text="Show Bottom Left" GridPane.rowIndex="6"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomCenterNC" styleClass="outline-button"
+               text="Show Bottom Center" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
+    <MFXButton minHeight="28.0" minWidth="90.0" onAction="#showBottomRightNC" styleClass="outline-button"
+               text="Show Bottom Right" GridPane.columnIndex="2" GridPane.rowIndex="6"/>
 </GridPane>

+ 28 - 28
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Pickers.fxml

@@ -7,32 +7,32 @@
 <GridPane alignment="CENTER" hgap="20.0" styleClass="grid-pane" stylesheets="@../css/Pickers.css" vgap="20.0"
           xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.PickersController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
-              GridPane.rowSpan="3">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Date Pickers" GridPane.columnSpan="3"/>
-   <MFXDatePicker promptText="Pick a date..." GridPane.rowIndex="1"/>
-   <MFXDatePicker id="custDatePicker" fx:id="custDatePicker" closePopupOnChange="false" floatMode="INLINE"
-                  floatingText="Custom" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
-   <MFXDatePicker disable="true" promptText="Disabled" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="3"
+               GridPane.rowSpan="3">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Date Pickers" GridPane.columnSpan="3"/>
+    <MFXDatePicker promptText="Pick a date..." GridPane.rowIndex="1"/>
+    <MFXDatePicker id="custDatePicker" fx:id="custDatePicker" closePopupOnChange="false" floatMode="INLINE"
+                   floatingText="Custom" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
+    <MFXDatePicker disable="true" promptText="Disabled" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
 </GridPane>

+ 64 - 64
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Progress.fxml

@@ -7,68 +7,68 @@
 <GridPane alignment="CENTER" hgap="20.0" styleClass="grid-pane" stylesheets="@../css/Progress.css" vgap="20.0"
           xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.ProgressController">
-   <columnConstraints>
-      <ColumnConstraints halignment="LEFT" prefWidth="90.0"/>
-      <ColumnConstraints halignment="CENTER" prefWidth="64.0"/>
-      <ColumnConstraints halignment="CENTER" prefWidth="64.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="64.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
-      <ColumnConstraints halignment="LEFT" minWidth="10.0" prefWidth="90.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="100.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="100.0"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="100.0"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="70.0"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="146.0" prefHeight="372.0" prefWidth="146.0" styleClass="grid-background"
-              GridPane.columnSpan="4" GridPane.rowSpan="2147483647">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Progress Bars" GridPane.columnSpan="4"/>
-   <Label styleClass="sub-header-label" text="Default" GridPane.rowIndex="1"/>
-   <MFXProgressBar GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
-   <Label styleClass="sub-header-label" text="Determinate" GridPane.rowIndex="2"/>
-   <MFXProgressBar id="determinateBar" fx:id="determinateBar" progress="0.0" GridPane.columnIndex="1"
-                   GridPane.columnSpan="3" GridPane.rowIndex="2"/>
-   <Label styleClass="sub-header-label" text="Custom 1" GridPane.rowIndex="3"/>
-   <MFXProgressBar id="customBar1" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="3"/>
-   <Label styleClass="sub-header-label" text="Custom 2" GridPane.rowIndex="4"/>
-   <MFXProgressBar id="customBar2" minHeight="8.0" GridPane.columnIndex="1" GridPane.columnSpan="3"
-                   GridPane.rowIndex="4"/>
-   <Label styleClass="sub-header-label" text="Disabled" GridPane.rowIndex="5"/>
-   <MFXProgressBar disable="true" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="5"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="5"
-              GridPane.columnSpan="4" GridPane.rowSpan="2147483647">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Progress Spinners"
-          GridPane.columnIndex="5" GridPane.columnSpan="4"/>
-   <Label styleClass="sub-header-label" text="Default" GridPane.columnIndex="5" GridPane.rowIndex="1"/>
-   <MFXProgressSpinner radius="24.0" GridPane.columnIndex="6" GridPane.rowIndex="1"/>
-   <Label styleClass="sub-header-label" text="Determinate" GridPane.columnIndex="5" GridPane.rowIndex="2"/>
-   <MFXProgressSpinner id="determinateSpinner" fx:id="determinateSpinner" progress="0.0" radius="24.0"
-                       GridPane.columnIndex="7" GridPane.rowIndex="2"/>
-   <Label styleClass="sub-header-label" text="Custom 1" GridPane.columnIndex="5" GridPane.rowIndex="3"/>
-   <MFXProgressSpinner id="customSpinner1" radius="24.0" GridPane.columnIndex="6" GridPane.rowIndex="3"/>
-   <Label styleClass="sub-header-label" text="Custom 2" GridPane.columnIndex="5" GridPane.rowIndex="4"/>
-   <MFXProgressSpinner id="customSpinner2" radius="24.0" GridPane.columnIndex="7" GridPane.rowIndex="4"/>
-   <Label styleClass="sub-header-label" text="Disabled" GridPane.columnIndex="5" GridPane.rowIndex="5"/>
-   <MFXProgressSpinner disable="true" radius="24.0" GridPane.columnIndex="6" GridPane.rowIndex="5"/>
+    <columnConstraints>
+        <ColumnConstraints halignment="LEFT" prefWidth="90.0"/>
+        <ColumnConstraints halignment="CENTER" prefWidth="64.0"/>
+        <ColumnConstraints halignment="CENTER" prefWidth="64.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="64.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="20.0"/>
+        <ColumnConstraints halignment="LEFT" minWidth="10.0" prefWidth="90.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="100.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="100.0"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0" prefWidth="100.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="70.0"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="146.0" prefHeight="372.0" prefWidth="146.0" styleClass="grid-background"
+               GridPane.columnSpan="4" GridPane.rowSpan="2147483647">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Progress Bars" GridPane.columnSpan="4"/>
+    <Label styleClass="sub-header-label" text="Default" GridPane.rowIndex="1"/>
+    <MFXProgressBar GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
+    <Label styleClass="sub-header-label" text="Determinate" GridPane.rowIndex="2"/>
+    <MFXProgressBar id="determinateBar" fx:id="determinateBar" progress="0.0" GridPane.columnIndex="1"
+                    GridPane.columnSpan="3" GridPane.rowIndex="2"/>
+    <Label styleClass="sub-header-label" text="Custom 1" GridPane.rowIndex="3"/>
+    <MFXProgressBar id="customBar1" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="3"/>
+    <Label styleClass="sub-header-label" text="Custom 2" GridPane.rowIndex="4"/>
+    <MFXProgressBar id="customBar2" minHeight="8.0" GridPane.columnIndex="1" GridPane.columnSpan="3"
+                    GridPane.rowIndex="4"/>
+    <Label styleClass="sub-header-label" text="Disabled" GridPane.rowIndex="5"/>
+    <MFXProgressBar disable="true" GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="5"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnIndex="5"
+               GridPane.columnSpan="4" GridPane.rowSpan="2147483647">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Progress Spinners"
+           GridPane.columnIndex="5" GridPane.columnSpan="4"/>
+    <Label styleClass="sub-header-label" text="Default" GridPane.columnIndex="5" GridPane.rowIndex="1"/>
+    <MFXProgressSpinner radius="24.0" GridPane.columnIndex="6" GridPane.rowIndex="1"/>
+    <Label styleClass="sub-header-label" text="Determinate" GridPane.columnIndex="5" GridPane.rowIndex="2"/>
+    <MFXProgressSpinner id="determinateSpinner" fx:id="determinateSpinner" progress="0.0" radius="24.0"
+                        GridPane.columnIndex="7" GridPane.rowIndex="2"/>
+    <Label styleClass="sub-header-label" text="Custom 1" GridPane.columnIndex="5" GridPane.rowIndex="3"/>
+    <MFXProgressSpinner id="customSpinner1" radius="24.0" GridPane.columnIndex="6" GridPane.rowIndex="3"/>
+    <Label styleClass="sub-header-label" text="Custom 2" GridPane.columnIndex="5" GridPane.rowIndex="4"/>
+    <MFXProgressSpinner id="customSpinner2" radius="24.0" GridPane.columnIndex="7" GridPane.rowIndex="4"/>
+    <Label styleClass="sub-header-label" text="Disabled" GridPane.columnIndex="5" GridPane.rowIndex="5"/>
+    <MFXProgressSpinner disable="true" radius="24.0" GridPane.columnIndex="6" GridPane.rowIndex="5"/>
 </GridPane>

+ 29 - 29
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/ScrollPanes.fxml

@@ -8,33 +8,33 @@
           stylesheets="@../css/Buttons.css" vgap="20.0" xmlns="http://javafx.com/javafx/17"
           xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.ScrollPanesController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2"
-              GridPane.rowSpan="3">
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Scroll Panes"
-          GridPane.columnSpan="2"/>
-   <MFXScrollPane fx:id="scroll1" fitToWidth="true" maxHeight="-Infinity" maxWidth="-Infinity" minWidth="-Infinity"
-                  prefHeight="150.0" prefWidth="250.0" GridPane.rowIndex="1"/>
-   <MFXScrollPane fx:id="scroll2" maxHeight="-Infinity" maxWidth="-Infinity" minWidth="-Infinity" prefHeight="150.0"
-                  prefWidth="250.0" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
-   <HBox alignment="CENTER" spacing="10.0" GridPane.columnSpan="2" GridPane.rowIndex="2">
-      <MFXButton onAction="#setRandomTrackColor" styleClass="outline-button" text="Random Track Color"/>
-      <MFXButton onAction="#setRandomThumbColor" styleClass="outline-button" text="Random Thumb Color"/>
-      <MFXButton onAction="#setRandomThumbHoverColor" styleClass="outline-button" text="Random Thumb Hover Color"/>
-   </HBox>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0" vgrow="SOMETIMES"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2"
+               GridPane.rowSpan="3">
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Scroll Panes"
+           GridPane.columnSpan="2"/>
+    <MFXScrollPane fx:id="scroll1" fitToWidth="true" maxHeight="-Infinity" maxWidth="-Infinity" minWidth="-Infinity"
+                   prefHeight="150.0" prefWidth="250.0" GridPane.rowIndex="1"/>
+    <MFXScrollPane fx:id="scroll2" maxHeight="-Infinity" maxWidth="-Infinity" minWidth="-Infinity" prefHeight="150.0"
+                   prefWidth="250.0" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
+    <HBox alignment="CENTER" spacing="10.0" GridPane.columnSpan="2" GridPane.rowIndex="2">
+        <MFXButton onAction="#setRandomTrackColor" styleClass="outline-button" text="Random Track Color"/>
+        <MFXButton onAction="#setRandomThumbColor" styleClass="outline-button" text="Random Thumb Color"/>
+        <MFXButton onAction="#setRandomThumbHoverColor" styleClass="outline-button" text="Random Thumb Hover Color"/>
+    </HBox>
 </GridPane>

+ 52 - 52
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Sliders.fxml

@@ -7,56 +7,56 @@
 <GridPane alignment="CENTER" hgap="20.0" styleClass="grid-pane" stylesheets="@../css/Sliders.css" vgap="20.0"
           xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.SlidersController">
-   <columnConstraints>
-      <ColumnConstraints halignment="LEFT" minWidth="10.0"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER" prefWidth="20.0"/>
-      <ColumnConstraints halignment="LEFT"/>
-      <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints prefHeight="64.0"/>
-      <RowConstraints prefHeight="64.0"/>
-      <RowConstraints prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="200.0"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
-              GridPane.rowSpan="2147483647">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Sliders" GridPane.columnSpan="2147483647"/>
-   <Label styleClass="sub-header-label" text="Default" GridPane.rowIndex="1"/>
-   <MFXSlider prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
-   <Label styleClass="sub-header-label" text="Custom" GridPane.rowIndex="2"/>
-   <MFXSlider id="customSlider" fx:id="customSlider" popupSide="OTHER_SIDE" prefWidth="150.0" GridPane.columnIndex="1"
-              GridPane.rowIndex="2"/>
-   <MFXSlider disable="true" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
-   <Label styleClass="sub-header-label" text="Disabled" GridPane.rowIndex="3"/>
-   <Label styleClass="sub-header-label" text="Bidirectional" GridPane.columnIndex="3" GridPane.rowIndex="1"/>
-   <MFXSlider min="-100.0" prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
-   <Label styleClass="sub-header-label" text="Ticks" GridPane.columnIndex="3" GridPane.rowIndex="2"/>
-   <MFXSlider minorTicksCount="4" prefWidth="150.0" showMajorTicks="true" showMinorTicks="true"
-              sliderMode="SNAP_TO_TICKS" tickUnit="20.0" GridPane.columnIndex="4" GridPane.rowIndex="2"/>
-   <Label styleClass="sub-header-label" text="Decimal Precision to 2" GridPane.columnIndex="3" GridPane.rowIndex="3"/>
-   <MFXSlider decimalPrecision="2" prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="3"/>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Vertical Sliders"
-          GridPane.columnSpan="2147483647" GridPane.rowIndex="4"/>
-   <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="20.0" GridPane.columnSpan="2147483647"
-         GridPane.rowIndex="5" GridPane.rowSpan="2147483647">
-      <MFXSlider orientation="VERTICAL" prefWidth="150.0"/>
-      <MFXSlider min="-100.0" minorTicksCount="4" orientation="VERTICAL" popupSide="OTHER_SIDE" prefWidth="150.0"
-                 showMajorTicks="true" showMinorTicks="true" sliderMode="SNAP_TO_TICKS"/>
-      <MFXSlider disable="true" orientation="VERTICAL" prefWidth="150.0"/>
-   </HBox>
+    <columnConstraints>
+        <ColumnConstraints halignment="LEFT" minWidth="10.0"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER" prefWidth="20.0"/>
+        <ColumnConstraints halignment="LEFT"/>
+        <ColumnConstraints halignment="CENTER" minWidth="10.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints prefHeight="64.0"/>
+        <RowConstraints prefHeight="64.0"/>
+        <RowConstraints prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="200.0"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
+               GridPane.rowSpan="2147483647">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Sliders" GridPane.columnSpan="2147483647"/>
+    <Label styleClass="sub-header-label" text="Default" GridPane.rowIndex="1"/>
+    <MFXSlider prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
+    <Label styleClass="sub-header-label" text="Custom" GridPane.rowIndex="2"/>
+    <MFXSlider id="customSlider" fx:id="customSlider" popupSide="OTHER_SIDE" prefWidth="150.0" GridPane.columnIndex="1"
+               GridPane.rowIndex="2"/>
+    <MFXSlider disable="true" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
+    <Label styleClass="sub-header-label" text="Disabled" GridPane.rowIndex="3"/>
+    <Label styleClass="sub-header-label" text="Bidirectional" GridPane.columnIndex="3" GridPane.rowIndex="1"/>
+    <MFXSlider min="-100.0" prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="1"/>
+    <Label styleClass="sub-header-label" text="Ticks" GridPane.columnIndex="3" GridPane.rowIndex="2"/>
+    <MFXSlider minorTicksCount="4" prefWidth="150.0" showMajorTicks="true" showMinorTicks="true"
+               sliderMode="SNAP_TO_TICKS" tickUnit="20.0" GridPane.columnIndex="4" GridPane.rowIndex="2"/>
+    <Label styleClass="sub-header-label" text="Decimal Precision to 2" GridPane.columnIndex="3" GridPane.rowIndex="3"/>
+    <MFXSlider decimalPrecision="2" prefWidth="150.0" GridPane.columnIndex="4" GridPane.rowIndex="3"/>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Vertical Sliders"
+           GridPane.columnSpan="2147483647" GridPane.rowIndex="4"/>
+    <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="20.0" GridPane.columnSpan="2147483647"
+          GridPane.rowIndex="5" GridPane.rowSpan="2147483647">
+        <MFXSlider orientation="VERTICAL" prefWidth="150.0"/>
+        <MFXSlider min="-100.0" minorTicksCount="4" orientation="VERTICAL" popupSide="OTHER_SIDE" prefWidth="150.0"
+                   showMajorTicks="true" showMinorTicks="true" sliderMode="SNAP_TO_TICKS"/>
+        <MFXSlider disable="true" orientation="VERTICAL" prefWidth="150.0"/>
+    </HBox>
 </GridPane>

+ 19 - 19
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/Stepper.fxml

@@ -8,23 +8,23 @@
 <GridPane maxHeight="-Infinity" maxWidth="-Infinity" stylesheets="@../css/Stepper.css"
           xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.StepperController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="10.0"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" prefHeight="40.0" valignment="CENTER" vgrow="SOMETIMES"/>
-      <RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
-   </padding>
-   <StackPane styleClass="grid-background" GridPane.rowSpan="2147483647">
-      <GridPane.margin>
-         <Insets bottom="-15.0" left="-15.0" right="-15.0" top="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Stepper"/>
-   <MFXButton fx:id="unlock" styleClass="outline-button" text="Unlock Mouse" GridPane.rowIndex="1"/>
-   <MFXStepper fx:id="stepper" minHeight="450.0" prefHeight="450.0" prefWidth="600.0" GridPane.rowIndex="2"/>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="10.0"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" prefHeight="40.0" valignment="CENTER" vgrow="SOMETIMES"/>
+        <RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
+    </padding>
+    <StackPane styleClass="grid-background" GridPane.rowSpan="2147483647">
+        <GridPane.margin>
+            <Insets bottom="-15.0" left="-15.0" right="-15.0" top="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Stepper"/>
+    <MFXButton fx:id="unlock" styleClass="outline-button" text="Unlock Mouse" GridPane.rowIndex="1"/>
+    <MFXStepper fx:id="stepper" minHeight="450.0" prefHeight="450.0" prefWidth="600.0" GridPane.rowIndex="2"/>
 </GridPane>

+ 3 - 3
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/TableViews.fxml

@@ -23,16 +23,16 @@
     <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
                GridPane.rowSpan="2147483647">
         <GridPane.margin>
-          <Insets bottom="-15.0" left="-15.0" right="-15.0"/>
+            <Insets bottom="-15.0" left="-15.0" right="-15.0"/>
         </GridPane.margin>
     </StackPane>
     <Label alignment="CENTER" maxWidth="1.7976931348623157E308" styleClass="header-label" text="Label"
            GridPane.columnSpan="2147483647">
         <GridPane.margin>
-          <Insets/>
+            <Insets/>
         </GridPane.margin>
         <padding>
-          <Insets bottom="10.0" top="10.0"/>
+            <Insets bottom="10.0" top="10.0"/>
         </padding>
     </Label>
     <MFXTableView fx:id="table" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0"

+ 68 - 66
demo/src/main/resources/io/github/palexdev/materialfx/demo/fxml/TextFields.fxml

@@ -7,70 +7,72 @@
 <GridPane alignment="CENTER" hgap="20.0" styleClass="grid-pane" stylesheets="@../css/TextFields.css" vgap="20.0"
           xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="io.github.palexdev.materialfx.demo.controllers.TextFieldsController">
-   <columnConstraints>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-      <ColumnConstraints halignment="CENTER"/>
-   </columnConstraints>
-   <rowConstraints>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="64.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="10.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="32.0"/>
-      <RowConstraints minHeight="10.0" prefHeight="150.0" valignment="BASELINE"/>
-   </rowConstraints>
-   <padding>
-      <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
-   </padding>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
-              GridPane.rowSpan="3">
-      <opaqueInsets>
-         <Insets/>
-      </opaqueInsets>
-      <GridPane.margin>
-         <Insets bottom="-7.0" left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Text Fields and Password Fields" GridPane.columnSpan="2147483647"/>
-   <MFXTextField floatingText="Inline Mode" GridPane.rowIndex="1"/>
-   <MFXTextField floatMode="BORDER" floatingText="Border Mode" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
-   <MFXTextField borderGap="2.0" floatMode="ABOVE" floatingText="Above Mode" GridPane.columnIndex="2"
-                 GridPane.rowIndex="1"/>
-   <MFXTextField floatMode="DISABLED" promptText="No Floating Text" GridPane.columnIndex="3" GridPane.rowIndex="1"/>
-   <MFXTextField disable="true" floatingText="Disabled" text="Text" GridPane.columnIndex="5" GridPane.rowIndex="1"/>
-   <MFXTextField id="customField" floatingText="Custom" promptText="Prompt Text" GridPane.columnIndex="4"
-                 GridPane.rowIndex="1"/>
-   <MFXPasswordField floatingText="Inline Mode" GridPane.rowIndex="2"/>
-   <MFXPasswordField floatMode="BORDER" floatingText="Border Mode" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
-   <MFXPasswordField borderGap="2.0" floatMode="ABOVE" floatingText="Above Mode" GridPane.columnIndex="2"
-                     GridPane.rowIndex="2"/>
-   <MFXPasswordField floatMode="DISABLED" promptText="No Floating Text" GridPane.columnIndex="3" GridPane.rowIndex="2"/>
-   <MFXPasswordField id="customPassword" floatingText="Custom" promptText="Prompt Text" GridPane.columnIndex="4"
-                     GridPane.rowIndex="2"/>
-   <MFXPasswordField disable="true" floatingText="Disabled" text="Text" GridPane.columnIndex="5" GridPane.rowIndex="2"/>
-   <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
-              GridPane.rowIndex="4" GridPane.rowSpan="2147483647">
-      <GridPane.margin>
-         <Insets bottom="-15.0" left="-15.0" right="-15.0"/>
-      </GridPane.margin>
-   </StackPane>
-   <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
-          styleClass="header-label" text="Features" GridPane.columnSpan="2147483647" GridPane.rowIndex="4"/>
-   <MFXTextField animated="false" floatingText="Not Animated" GridPane.rowIndex="5"/>
-   <MFXTextField allowEdit="false" caretVisible="false" floatingText="As Label" selectable="false" text="Label's text"
-                 GridPane.columnIndex="1" GridPane.rowIndex="5"/>
-   <MFXTextField fx:id="textField" floatingText="Characters Limit" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
-   <VBox spacing="5.0" GridPane.columnIndex="3" GridPane.columnSpan="2147483647" GridPane.rowIndex="5">
-      <padding>
-         <Insets right="10.0"/>
-      </padding>
-      <MFXPasswordField id="validatedField" fx:id="passwordField" floatingText="Validated" maxWidth="200.0"/>
-      <Label id="validationLabel" fx:id="validationLabel" maxWidth="1.7976931348623157E308" minHeight="-Infinity"
-             textFill="#ef6e6b" visible="false" wrapText="true"/>
-   </VBox>
+    <columnConstraints>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+        <ColumnConstraints halignment="CENTER"/>
+    </columnConstraints>
+    <rowConstraints>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="64.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="10.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="32.0"/>
+        <RowConstraints minHeight="10.0" prefHeight="150.0" valignment="BASELINE"/>
+    </rowConstraints>
+    <padding>
+        <Insets bottom="20.0" left="30.0" right="30.0" top="20.0"/>
+    </padding>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
+               GridPane.rowSpan="3">
+        <opaqueInsets>
+            <Insets/>
+        </opaqueInsets>
+        <GridPane.margin>
+            <Insets bottom="-7.0" left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Text Fields and Password Fields" GridPane.columnSpan="2147483647"/>
+    <MFXTextField floatingText="Inline Mode" GridPane.rowIndex="1"/>
+    <MFXTextField floatMode="BORDER" floatingText="Border Mode" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
+    <MFXTextField borderGap="2.0" floatMode="ABOVE" floatingText="Above Mode" GridPane.columnIndex="2"
+                  GridPane.rowIndex="1"/>
+    <MFXTextField floatMode="DISABLED" promptText="No Floating Text" GridPane.columnIndex="3" GridPane.rowIndex="1"/>
+    <MFXTextField disable="true" floatingText="Disabled" text="Text" GridPane.columnIndex="5" GridPane.rowIndex="1"/>
+    <MFXTextField id="customField" floatingText="Custom" promptText="Prompt Text" GridPane.columnIndex="4"
+                  GridPane.rowIndex="1"/>
+    <MFXPasswordField floatingText="Inline Mode" GridPane.rowIndex="2"/>
+    <MFXPasswordField floatMode="BORDER" floatingText="Border Mode" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
+    <MFXPasswordField borderGap="2.0" floatMode="ABOVE" floatingText="Above Mode" GridPane.columnIndex="2"
+                      GridPane.rowIndex="2"/>
+    <MFXPasswordField floatMode="DISABLED" promptText="No Floating Text" GridPane.columnIndex="3"
+                      GridPane.rowIndex="2"/>
+    <MFXPasswordField id="customPassword" floatingText="Custom" promptText="Prompt Text" GridPane.columnIndex="4"
+                      GridPane.rowIndex="2"/>
+    <MFXPasswordField disable="true" floatingText="Disabled" text="Text" GridPane.columnIndex="5"
+                      GridPane.rowIndex="2"/>
+    <StackPane minHeight="150.0" minWidth="300.0" styleClass="grid-background" GridPane.columnSpan="2147483647"
+               GridPane.rowIndex="4" GridPane.rowSpan="2147483647">
+        <GridPane.margin>
+            <Insets bottom="-15.0" left="-15.0" right="-15.0"/>
+        </GridPane.margin>
+    </StackPane>
+    <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
+           styleClass="header-label" text="Features" GridPane.columnSpan="2147483647" GridPane.rowIndex="4"/>
+    <MFXTextField animated="false" floatingText="Not Animated" GridPane.rowIndex="5"/>
+    <MFXTextField allowEdit="false" caretVisible="false" floatingText="As Label" selectable="false" text="Label's text"
+                  GridPane.columnIndex="1" GridPane.rowIndex="5"/>
+    <MFXTextField fx:id="textField" floatingText="Characters Limit" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
+    <VBox spacing="5.0" GridPane.columnIndex="3" GridPane.columnSpan="2147483647" GridPane.rowIndex="5">
+        <padding>
+            <Insets right="10.0"/>
+        </padding>
+        <MFXPasswordField id="validatedField" fx:id="passwordField" floatingText="Validated" maxWidth="200.0"/>
+        <Label id="validationLabel" fx:id="validationLabel" maxWidth="1.7976931348623157E308" minHeight="-Infinity"
+               textFill="#ef6e6b" visible="false" wrapText="true"/>
+    </VBox>
 </GridPane>

+ 21 - 21
demo/src/test/java/BorderWithGap.java

@@ -7,28 +7,28 @@ import javafx.stage.Stage;
 
 public class BorderWithGap extends Application {
 
-    // Background
-    @Override
-    public void start(Stage primaryStage) {
-        AnchorPane pane = new AnchorPane();
+	// Background
+	@Override
+	public void start(Stage primaryStage) {
+		AnchorPane pane = new AnchorPane();
 
-        Label label = new Label("Border with gap");
-        AnchorPane.setTopAnchor(label, 50.0);
-        AnchorPane.setLeftAnchor(label, 50.0);
-        label.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
-        pane.getChildren().add(label);
+		Label label = new Label("Border with gap");
+		AnchorPane.setTopAnchor(label, 50.0);
+		AnchorPane.setLeftAnchor(label, 50.0);
+		label.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
+		pane.getChildren().add(label);
 
-        label.setStyle(
-                """
-                -fx-background-color: blue, -fx-background, -fx-background;
-                -fx-background-insets: 0, 0 10 38 10, 1;
-                -fx-background-radius: 5, 0, 3;
-                -fx-padding: 10;
-                """
-        );
+		label.setStyle(
+				"""
+						-fx-background-color: blue, -fx-background, -fx-background;
+						-fx-background-insets: 0, 0 10 38 10, 1;
+						-fx-background-radius: 5, 0, 3;
+						-fx-padding: 10;
+						"""
+		);
 
-        Scene scene = new Scene(pane, 600, 600);
-        primaryStage.setScene(scene);
-        primaryStage.show();
-    }
+		Scene scene = new Scene(pane, 600, 600);
+		primaryStage.setScene(scene);
+		primaryStage.show();
+	}
 }

+ 9 - 9
demo/src/test/java/FilterPaneTest.java

@@ -20,15 +20,15 @@ import org.scenicview.ScenicView;
 
 public class FilterPaneTest extends Application {
 	private String text =
-            """
-			Lorem Ipsum is simply dummy text of the printing and typesetting industry.
-			Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
-			when an unknown printer took a galley of type and scrambled it to make a type specimen book.
-			It has survived not only five centuries, but also the leap into electronic typesetting,
-			remaining essentially unchanged.
-			It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
-			and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
-			""";
+			"""
+					Lorem Ipsum is simply dummy text of the printing and typesetting industry.
+					Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
+					when an unknown printer took a galley of type and scrambled it to make a type specimen book.
+					It has survived not only five centuries, but also the leap into electronic typesetting,
+					remaining essentially unchanged.
+					It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
+					and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
+					""";
 	private MFXStageDialog dialog;
 
 	@Override

+ 1 - 1
demo/src/test/java/FloatingStyle.java

@@ -1,3 +1,3 @@
 public enum FloatingStyle {
-    FLOATING, IFTA
+	FLOATING, IFTA
 }

+ 4 - 4
demo/src/test/java/Launcher.java

@@ -2,8 +2,8 @@ import javafx.application.Application;
 
 public class Launcher {
 
-    public static void main(String[] args) {
-        System.setProperty("prism.text", "t2k");
-        Application.launch(Playground.class, args);
-    }
+	public static void main(String[] args) {
+		System.setProperty("prism.text", "t2k");
+		Application.launch(Playground.class, args);
+	}
 }

+ 155 - 155
demo/src/test/java/MFXLabelRework.java

@@ -8,159 +8,159 @@ import javafx.scene.control.Skin;
 import java.util.List;
 
 public class MFXLabelRework extends Labeled {
-    private final String STYLE_CLASS = "mfx-label";
-    private final String STYLESHEET = "";
-
-    private final StringProperty floatingText = new SimpleStringProperty("");
-    private final ObjectProperty<Node> trailingIcon = new SimpleObjectProperty<>();
-
-    protected static final PseudoClass EDITING_PSEUDO_CLASS = PseudoClass.getPseudoClass("editing");
-    private final BooleanProperty editing = new SimpleBooleanProperty();
-
-    public MFXLabelRework() {
-        this("");
-    }
-
-    public MFXLabelRework(String text) {
-        this(text, null);
-    }
-
-    public MFXLabelRework(String text, String floatingText) {
-        this(text, floatingText, null);
-    }
-
-    public MFXLabelRework(String text, String floatingText, Node graphic) {
-        super(text, graphic);
-        setFloatingText(floatingText);
-        initialize();
-    }
-
-    private void initialize() {
-        getStyleClass().add(STYLE_CLASS);
-        editing.addListener(invalidated -> pseudoClassStateChanged(EDITING_PSEUDO_CLASS, editing.get()));
-    }
-
-    public String getFloatingText() {
-        return floatingText.get();
-    }
-
-    public StringProperty floatingTextProperty() {
-        return floatingText;
-    }
-
-    public void setFloatingText(String floatingText) {
-        this.floatingText.set(floatingText);
-    }
-
-    public Node getTrailingIcon() {
-        return trailingIcon.get();
-    }
-
-    public ObjectProperty<Node> trailingIconProperty() {
-        return trailingIcon;
-    }
-
-    public void setTrailingIcon(Node trailingIcon) {
-        this.trailingIcon.set(trailingIcon);
-    }
-
-    public boolean isEditing() {
-        return editing.get();
-    }
-
-    public BooleanProperty editingProperty() {
-        return editing;
-    }
-
-    public void setEditing(boolean editing) {
-        this.editing.set(editing);
-    }
-
-    private final StyleableBooleanProperty editable = new SimpleStyleableBooleanProperty(
-            StyleableProperties.EDITABLE,
-            this,
-            "editable",
-            false
-    ) {
-        @Override
-        public StyleOrigin getStyleOrigin() {
-            return StyleOrigin.USER_AGENT;
-        }
-    };
-
-    private final StyleableDoubleProperty gap = new SimpleStyleableDoubleProperty(
-            StyleableProperties.GAP,
-            this,
-            "gap",
-            3.0
-    ) {
-        @Override
-        public StyleOrigin getStyleOrigin() {
-            return StyleOrigin.USER_AGENT;
-        }
-    };
-
-    public boolean isEditable() {
-        return editable.get();
-    }
-
-    public StyleableBooleanProperty editableProperty() {
-        return editable;
-    }
-
-    public void setEditable(boolean editable) {
-        this.editable.set(editable);
-    }
-
-    public double getGap() {
-        return gap.get();
-    }
-
-    public StyleableDoubleProperty gapProperty() {
-        return gap;
-    }
-
-    public void setGap(double gap) {
-        this.gap.set(gap);
-    }
-
-    private static class StyleableProperties {
-        private static final StyleablePropertyFactory<MFXLabelRework> FACTORY = new StyleablePropertyFactory<>(Labeled.getClassCssMetaData());
-        private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
-
-        private static final CssMetaData<MFXLabelRework, Boolean> EDITABLE =
-                FACTORY.createBooleanCssMetaData(
-                        "-mfx-editable",
-                        MFXLabelRework::editableProperty,
-                        false
-                );
-
-        private static final CssMetaData<MFXLabelRework, Number> GAP =
-                FACTORY.createSizeCssMetaData(
-                        "-mfx-gap",
-                        MFXLabelRework::gapProperty,
-                        3.0
-                );
-
-        static {
-            cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
-                    Labeled.getClassCssMetaData(),
-                    EDITABLE, GAP
-            );
-        }
-    }
-
-    public static List<CssMetaData<? extends Styleable, ?>> getControlCssMetaDataList() {
-        return StyleableProperties.cssMetaDataList;
-    }
-
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new MFXLabelSkinRework(this);
-    }
-
-    @Override
-    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
-        return MFXLabelRework.getControlCssMetaDataList();
-    }
+	private final String STYLE_CLASS = "mfx-label";
+	private final String STYLESHEET = "";
+
+	private final StringProperty floatingText = new SimpleStringProperty("");
+	private final ObjectProperty<Node> trailingIcon = new SimpleObjectProperty<>();
+
+	protected static final PseudoClass EDITING_PSEUDO_CLASS = PseudoClass.getPseudoClass("editing");
+	private final BooleanProperty editing = new SimpleBooleanProperty();
+
+	public MFXLabelRework() {
+		this("");
+	}
+
+	public MFXLabelRework(String text) {
+		this(text, null);
+	}
+
+	public MFXLabelRework(String text, String floatingText) {
+		this(text, floatingText, null);
+	}
+
+	public MFXLabelRework(String text, String floatingText, Node graphic) {
+		super(text, graphic);
+		setFloatingText(floatingText);
+		initialize();
+	}
+
+	private void initialize() {
+		getStyleClass().add(STYLE_CLASS);
+		editing.addListener(invalidated -> pseudoClassStateChanged(EDITING_PSEUDO_CLASS, editing.get()));
+	}
+
+	public String getFloatingText() {
+		return floatingText.get();
+	}
+
+	public StringProperty floatingTextProperty() {
+		return floatingText;
+	}
+
+	public void setFloatingText(String floatingText) {
+		this.floatingText.set(floatingText);
+	}
+
+	public Node getTrailingIcon() {
+		return trailingIcon.get();
+	}
+
+	public ObjectProperty<Node> trailingIconProperty() {
+		return trailingIcon;
+	}
+
+	public void setTrailingIcon(Node trailingIcon) {
+		this.trailingIcon.set(trailingIcon);
+	}
+
+	public boolean isEditing() {
+		return editing.get();
+	}
+
+	public BooleanProperty editingProperty() {
+		return editing;
+	}
+
+	public void setEditing(boolean editing) {
+		this.editing.set(editing);
+	}
+
+	private final StyleableBooleanProperty editable = new SimpleStyleableBooleanProperty(
+			StyleableProperties.EDITABLE,
+			this,
+			"editable",
+			false
+	) {
+		@Override
+		public StyleOrigin getStyleOrigin() {
+			return StyleOrigin.USER_AGENT;
+		}
+	};
+
+	private final StyleableDoubleProperty gap = new SimpleStyleableDoubleProperty(
+			StyleableProperties.GAP,
+			this,
+			"gap",
+			3.0
+	) {
+		@Override
+		public StyleOrigin getStyleOrigin() {
+			return StyleOrigin.USER_AGENT;
+		}
+	};
+
+	public boolean isEditable() {
+		return editable.get();
+	}
+
+	public StyleableBooleanProperty editableProperty() {
+		return editable;
+	}
+
+	public void setEditable(boolean editable) {
+		this.editable.set(editable);
+	}
+
+	public double getGap() {
+		return gap.get();
+	}
+
+	public StyleableDoubleProperty gapProperty() {
+		return gap;
+	}
+
+	public void setGap(double gap) {
+		this.gap.set(gap);
+	}
+
+	private static class StyleableProperties {
+		private static final StyleablePropertyFactory<MFXLabelRework> FACTORY = new StyleablePropertyFactory<>(Labeled.getClassCssMetaData());
+		private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
+
+		private static final CssMetaData<MFXLabelRework, Boolean> EDITABLE =
+				FACTORY.createBooleanCssMetaData(
+						"-mfx-editable",
+						MFXLabelRework::editableProperty,
+						false
+				);
+
+		private static final CssMetaData<MFXLabelRework, Number> GAP =
+				FACTORY.createSizeCssMetaData(
+						"-mfx-gap",
+						MFXLabelRework::gapProperty,
+						3.0
+				);
+
+		static {
+			cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
+					Labeled.getClassCssMetaData(),
+					EDITABLE, GAP
+			);
+		}
+	}
+
+	public static List<CssMetaData<? extends Styleable, ?>> getControlCssMetaDataList() {
+		return StyleableProperties.cssMetaDataList;
+	}
+
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new MFXLabelSkinRework(this);
+	}
+
+	@Override
+	public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
+		return MFXLabelRework.getControlCssMetaDataList();
+	}
 }

+ 159 - 159
demo/src/test/java/MFXLabelSkinRework.java

@@ -8,163 +8,163 @@ import javafx.scene.input.MouseEvent;
 import javafx.scene.text.Text;
 
 public class MFXLabelSkinRework extends SkinBase<MFXLabelRework> {
-    private final BoundLabel text;
-    private final Text floatingText;
-
-    private final TextField editor;
-    private boolean commitChanges = false;
-
-    public MFXLabelSkinRework(MFXLabelRework label) {
-        super(label);
-
-        text = new BoundLabel(label);
-        text.graphicProperty().unbind();
-        text.setGraphic(null);
-        text.setMaxWidth(Double.MAX_VALUE);
-
-        floatingText = new Text();
-        floatingText.textProperty().bind(label.floatingTextProperty());
-
-        editor = new TextField();
-        editor.getStyleClass().add("editor");
-        editor.setManaged(false);
-        editor.setVisible(false);
-
-        getChildren().addAll(text, floatingText, editor);
-        if (label.getGraphic() != null) getChildren().add(0, label.getGraphic());
-        if (label.getTrailingIcon() != null) getChildren().add(0, label.getTrailingIcon());
-        addListeners();
-    }
-
-    private void addListeners() {
-        MFXLabelRework label = getSkinnable();
-
-        label.graphicProperty().addListener((observable, oldValue, newValue) -> {
-            if (oldValue != null) getChildren().remove(oldValue);
-            if (newValue != null) getChildren().add(0, newValue);
-        });
-        label.trailingIconProperty().addListener((observable, oldValue, newValue) -> {
-            if (oldValue != null) getChildren().remove(oldValue);
-            if (newValue != null) getChildren().remove(newValue);
-        });
-        label.gapProperty().addListener(invalidated -> label.requestLayout());
-
-        label.editingProperty().addListener((observable, oldValue, newValue) -> showEditor(newValue));
-        label.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
-            if (!label.isEditable()) return;
-            if (event.getClickCount() >= 2 && event.getClickCount() % 2 == 0 && !label.isEditing()) {
-                label.setEditing(true);
-            }
-        });
-
-        label.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
-            if (event.getCode() == KeyCode.ENTER) {
-                commitChanges = true;
-                label.setEditing(false);
-            } else if (event.getCode() == KeyCode.ESCAPE) {
-                commitChanges = false;
-                label.setEditing(false);
-            }
-        });
-        editor.focusedProperty().addListener((observable, oldValue, newValue) -> {
-            if (!newValue && label.isEditing()) {
-                commitChanges = true;
-                label.setEditing(false);
-            }
-        });
-
-    }
-
-    protected void showEditor(boolean show) {
-        MFXLabelRework label = getSkinnable();
-        if (show) {
-            text.setVisible(false);
-            editor.setText(label.getText());
-            editor.setVisible(true);
-            editor.requestFocus();
-            editor.positionCaret(editor.getText().length());
-        } else {
-            if (commitChanges) label.setText(editor.getText());
-            editor.setVisible(false);
-            text.setVisible(true);
-        }
-        commitChanges = false;
-    }
-
-    @Override
-    protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
-        return topInset +
-                floatingText.prefHeight(-1) +
-                getSkinnable().getGap() +
-                text.prefHeight(-1) +
-                bottomInset;
-    }
-
-    @Override
-    protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        MFXLabelRework label = getSkinnable();
-        Node graphic = label.getGraphic();
-        Node trailing = label.getTrailingIcon();
-        return leftInset +
-                ((graphic != null) ? graphic.prefWidth(-1) + label.getGraphicTextGap() : 0) +
-                Math.max(floatingText.prefWidth(-1), text.prefWidth(-1)) +
-                ((trailing != null) ? label.getGraphicTextGap() + trailing.prefWidth(-1) : 0) +
-                rightInset;
-    }
-
-    @Override
-    protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        return getSkinnable().prefWidth(-1);
-    }
-
-    @Override
-    protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
-        return getSkinnable().prefHeight(-1);
-    }
-
-    @Override
-    protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) {
-        MFXLabelRework label = getSkinnable();
-        text.autosize();
-        floatingText.autosize();
-
-        Node graphic = label.getGraphic();
-        Node trailingIcon = label.getTrailingIcon();
-
-        // Graphic
-        double graphicW = 0;
-        double graphicH;
-        double graphicX = snappedLeftInset();
-        double graphicY;
-        if (graphic != null) {
-            graphic.autosize();
-            graphicW = graphic.prefWidth(-1);
-            graphicH = graphic.prefHeight(-1);
-            graphicY = (contentHeight / 2) - (graphicH / 2) + snappedTopInset();
-            graphic.relocate(snapPositionX(graphicX), snapPositionY(graphicY));
-        }
-
-        // Texts and Editor
-        double floatW = floatingText.prefWidth(-1);
-        double floatH = floatingText.prefHeight(-1);
-        double floatX = graphicX + graphicW + ((graphic != null) ? label.getGraphicTextGap() : 0);
-        double floatY = snappedTopInset();
-        floatingText.relocate(snapPositionX(floatX), snapPositionY(floatY));
-
-        double textW = text.prefWidth(-1);
-        double textY = floatY + label.getGap() + floatH;
-        text.relocate(snapPositionX(floatX), snapPositionY(textY));
-
-        double editorH = text.prefHeight(-1);
-        editor.resizeRelocate(snapPositionX(floatX), snapPositionY(textY), textW, editorH);
-
-        // Trailing
-        if (trailingIcon != null) {
-            trailingIcon.autosize();
-            double trailingH = trailingIcon.prefHeight(-1);
-            double trailingX = floatX + Math.max(textW, floatW) + label.getGraphicTextGap();
-            double trailingY = (contentHeight / 2) - (trailingH / 2) + snappedTopInset();
-            trailingIcon.relocate(snapPositionX(trailingX), snapPositionY(trailingY));
-        }
-    }
+	private final BoundLabel text;
+	private final Text floatingText;
+
+	private final TextField editor;
+	private boolean commitChanges = false;
+
+	public MFXLabelSkinRework(MFXLabelRework label) {
+		super(label);
+
+		text = new BoundLabel(label);
+		text.graphicProperty().unbind();
+		text.setGraphic(null);
+		text.setMaxWidth(Double.MAX_VALUE);
+
+		floatingText = new Text();
+		floatingText.textProperty().bind(label.floatingTextProperty());
+
+		editor = new TextField();
+		editor.getStyleClass().add("editor");
+		editor.setManaged(false);
+		editor.setVisible(false);
+
+		getChildren().addAll(text, floatingText, editor);
+		if (label.getGraphic() != null) getChildren().add(0, label.getGraphic());
+		if (label.getTrailingIcon() != null) getChildren().add(0, label.getTrailingIcon());
+		addListeners();
+	}
+
+	private void addListeners() {
+		MFXLabelRework label = getSkinnable();
+
+		label.graphicProperty().addListener((observable, oldValue, newValue) -> {
+			if (oldValue != null) getChildren().remove(oldValue);
+			if (newValue != null) getChildren().add(0, newValue);
+		});
+		label.trailingIconProperty().addListener((observable, oldValue, newValue) -> {
+			if (oldValue != null) getChildren().remove(oldValue);
+			if (newValue != null) getChildren().remove(newValue);
+		});
+		label.gapProperty().addListener(invalidated -> label.requestLayout());
+
+		label.editingProperty().addListener((observable, oldValue, newValue) -> showEditor(newValue));
+		label.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
+			if (!label.isEditable()) return;
+			if (event.getClickCount() >= 2 && event.getClickCount() % 2 == 0 && !label.isEditing()) {
+				label.setEditing(true);
+			}
+		});
+
+		label.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
+			if (event.getCode() == KeyCode.ENTER) {
+				commitChanges = true;
+				label.setEditing(false);
+			} else if (event.getCode() == KeyCode.ESCAPE) {
+				commitChanges = false;
+				label.setEditing(false);
+			}
+		});
+		editor.focusedProperty().addListener((observable, oldValue, newValue) -> {
+			if (!newValue && label.isEditing()) {
+				commitChanges = true;
+				label.setEditing(false);
+			}
+		});
+
+	}
+
+	protected void showEditor(boolean show) {
+		MFXLabelRework label = getSkinnable();
+		if (show) {
+			text.setVisible(false);
+			editor.setText(label.getText());
+			editor.setVisible(true);
+			editor.requestFocus();
+			editor.positionCaret(editor.getText().length());
+		} else {
+			if (commitChanges) label.setText(editor.getText());
+			editor.setVisible(false);
+			text.setVisible(true);
+		}
+		commitChanges = false;
+	}
+
+	@Override
+	protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+		return topInset +
+				floatingText.prefHeight(-1) +
+				getSkinnable().getGap() +
+				text.prefHeight(-1) +
+				bottomInset;
+	}
+
+	@Override
+	protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+		MFXLabelRework label = getSkinnable();
+		Node graphic = label.getGraphic();
+		Node trailing = label.getTrailingIcon();
+		return leftInset +
+				((graphic != null) ? graphic.prefWidth(-1) + label.getGraphicTextGap() : 0) +
+				Math.max(floatingText.prefWidth(-1), text.prefWidth(-1)) +
+				((trailing != null) ? label.getGraphicTextGap() + trailing.prefWidth(-1) : 0) +
+				rightInset;
+	}
+
+	@Override
+	protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+		return getSkinnable().prefWidth(-1);
+	}
+
+	@Override
+	protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+		return getSkinnable().prefHeight(-1);
+	}
+
+	@Override
+	protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) {
+		MFXLabelRework label = getSkinnable();
+		text.autosize();
+		floatingText.autosize();
+
+		Node graphic = label.getGraphic();
+		Node trailingIcon = label.getTrailingIcon();
+
+		// Graphic
+		double graphicW = 0;
+		double graphicH;
+		double graphicX = snappedLeftInset();
+		double graphicY;
+		if (graphic != null) {
+			graphic.autosize();
+			graphicW = graphic.prefWidth(-1);
+			graphicH = graphic.prefHeight(-1);
+			graphicY = (contentHeight / 2) - (graphicH / 2) + snappedTopInset();
+			graphic.relocate(snapPositionX(graphicX), snapPositionY(graphicY));
+		}
+
+		// Texts and Editor
+		double floatW = floatingText.prefWidth(-1);
+		double floatH = floatingText.prefHeight(-1);
+		double floatX = graphicX + graphicW + ((graphic != null) ? label.getGraphicTextGap() : 0);
+		double floatY = snappedTopInset();
+		floatingText.relocate(snapPositionX(floatX), snapPositionY(floatY));
+
+		double textW = text.prefWidth(-1);
+		double textY = floatY + label.getGap() + floatH;
+		text.relocate(snapPositionX(floatX), snapPositionY(textY));
+
+		double editorH = text.prefHeight(-1);
+		editor.resizeRelocate(snapPositionX(floatX), snapPositionY(textY), textW, editorH);
+
+		// Trailing
+		if (trailingIcon != null) {
+			trailingIcon.autosize();
+			double trailingH = trailingIcon.prefHeight(-1);
+			double trailingX = floatX + Math.max(textW, floatW) + label.getGraphicTextGap();
+			double trailingY = (contentHeight / 2) - (trailingH / 2) + snappedTopInset();
+			trailingIcon.relocate(snapPositionX(trailingX), snapPositionY(trailingY));
+		}
+	}
 }

+ 47 - 47
demo/src/test/java/NotificationsTest.java

@@ -27,58 +27,58 @@ import java.util.stream.IntStream;
 
 public class NotificationsTest extends Application {
 
-    @Override
-    public void start(Stage primaryStage) throws Exception {
-        StackPane stackPane = new StackPane();
+	@Override
+	public void start(Stage primaryStage) throws Exception {
+		StackPane stackPane = new StackPane();
 
-        MFXNotificationCenter notificationCenter = new MFXNotificationCenter();
-        notificationCenter.getStylesheets().add(MFXResourcesLoader.load("css/MFXNotificationCenter.css"));
-        IntStream.range(0, 100).forEach(i -> notificationCenter.getNotifications().add(createDummyNotification()));
-        stackPane.getChildren().add(notificationCenter);
+		MFXNotificationCenter notificationCenter = new MFXNotificationCenter();
+		notificationCenter.getStylesheets().add(MFXResourcesLoader.load("css/MFXNotificationCenter.css"));
+		IntStream.range(0, 100).forEach(i -> notificationCenter.getNotifications().add(createDummyNotification()));
+		stackPane.getChildren().add(notificationCenter);
 
-        MFXNotificationCenterSystem.instance()
-                .initOwner(primaryStage)
-                .setOpenOnNew(false)
-                .setCloseAutomatically(true)
-                .setPosition(NotificationPos.TOP_LEFT);
-        MFXNotificationSystem.instance()
-                .initOwner(primaryStage)
-                .setPosition(NotificationPos.TOP_RIGHT);
-        stackPane.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
-            switch (event.getCode()) {
-                case A -> MFXNotificationCenterSystem.instance().publish(createDummyNotification());
-                case C -> notificationCenter.stopNotificationsUpdater();
-                case S -> notificationCenter.startNotificationsUpdater(60, TimeUnit.SECONDS);
-                case T -> MFXNotificationSystem.instance().publish(createDummyNotification());
-                case P -> MFXNotificationCenterSystem.instance().delaySetPosition(NotificationPos.TOP_LEFT);
-            }
-        });
+		MFXNotificationCenterSystem.instance()
+				.initOwner(primaryStage)
+				.setOpenOnNew(false)
+				.setCloseAutomatically(true)
+				.setPosition(NotificationPos.TOP_LEFT);
+		MFXNotificationSystem.instance()
+				.initOwner(primaryStage)
+				.setPosition(NotificationPos.TOP_RIGHT);
+		stackPane.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
+			switch (event.getCode()) {
+				case A -> MFXNotificationCenterSystem.instance().publish(createDummyNotification());
+				case C -> notificationCenter.stopNotificationsUpdater();
+				case S -> notificationCenter.startNotificationsUpdater(60, TimeUnit.SECONDS);
+				case T -> MFXNotificationSystem.instance().publish(createDummyNotification());
+				case P -> MFXNotificationCenterSystem.instance().delaySetPosition(NotificationPos.TOP_LEFT);
+			}
+		});
 
-        Scene scene = new Scene(stackPane, 800, 600);
-        primaryStage.setScene(scene);
-        primaryStage.show();
+		Scene scene = new Scene(stackPane, 800, 600);
+		primaryStage.setScene(scene);
+		primaryStage.show();
 
-        ScenicView.show(notificationCenter.getScene());
-    }
+		ScenicView.show(notificationCenter.getScene());
+	}
 
-    private INotification createDummyNotification() {
-        MFXTextField label = MFXTextField.asLabel("Random Label n." + RandomUtils.random.nextInt());
-        label.setLeadingIcon(new MFXIconWrapper(MFXFontIcon.getRandomIcon(18, ColorUtils.getRandomColor()), 24));
-        label.setAlignment(Pos.CENTER_LEFT);
-        label.setMaxWidth(Double.MAX_VALUE);
-        HBox.setHgrow(label, Priority.ALWAYS);
+	private INotification createDummyNotification() {
+		MFXTextField label = MFXTextField.asLabel("Random Label n." + RandomUtils.random.nextInt());
+		label.setLeadingIcon(new MFXIconWrapper(MFXFontIcon.getRandomIcon(18, ColorUtils.getRandomColor()), 24));
+		label.setAlignment(Pos.CENTER_LEFT);
+		label.setMaxWidth(Double.MAX_VALUE);
+		HBox.setHgrow(label, Priority.ALWAYS);
 
-        MFXTextField time = MFXTextField.asLabel();
-        time.setAlignment(Pos.CENTER_RIGHT);
+		MFXTextField time = MFXTextField.asLabel();
+		time.setAlignment(Pos.CENTER_RIGHT);
 
-        HBox box = new HBox(label, time);
-        box.setMinSize(450, -1);
-        box.setStyle("-fx-background-color: white");
-        box.setAlignment(Pos.CENTER_LEFT);
-        box.setPadding(InsetsFactory.right(20));
-        MFXSimpleNotification notification = new MFXSimpleNotification(box);
-        notification.setOnUpdateElapsed((longElapsed, stringElapsed) -> Platform.runLater(() -> time.setText(stringElapsed)));
-        time.setText(notification.getTimeToStringConverter().apply(notification.getElapsedTime()));
-        return notification;
-    }
+		HBox box = new HBox(label, time);
+		box.setMinSize(450, -1);
+		box.setStyle("-fx-background-color: white");
+		box.setAlignment(Pos.CENTER_LEFT);
+		box.setPadding(InsetsFactory.right(20));
+		MFXSimpleNotification notification = new MFXSimpleNotification(box);
+		notification.setOnUpdateElapsed((longElapsed, stringElapsed) -> Platform.runLater(() -> time.setText(stringElapsed)));
+		time.setText(notification.getTimeToStringConverter().apply(notification.getElapsedTime()));
+		return notification;
+	}
 }

+ 49 - 49
demo/src/test/java/PopupTest.java

@@ -27,59 +27,59 @@ import java.util.List;
 
 public class PopupTest extends Application {
 
-    @Override
-    public void start(Stage primaryStage) throws Exception {
-        StackPane stackPane = new StackPane() {
-            @Override
-            public String getUserAgentStylesheet() {
-                return Launcher.class.getResource("PopupTest.css").toExternalForm();
-            }
-        };
-        //stackPane.getStylesheets().add(Launcher.class.getResource("PopupTest.css").toExternalForm());
+	@Override
+	public void start(Stage primaryStage) throws Exception {
+		StackPane stackPane = new StackPane() {
+			@Override
+			public String getUserAgentStylesheet() {
+				return Launcher.class.getResource("PopupTest.css").toExternalForm();
+			}
+		};
+		//stackPane.getStylesheets().add(Launcher.class.getResource("PopupTest.css").toExternalForm());
 
-        MFXButton button = new MFXButton("SHOW");
-        button.backgroundProperty().addListener((observable, oldValue, newValue) -> {
-            List<BackgroundFill> fills = newValue.getFills();
-            Paint[] colors = fills.stream().map(BackgroundFill::getFill).toArray(Paint[]::new);
-            System.out.println(Arrays.toString(colors));
-        });
-        button.setPrefSize(180, 36);
-        button.setButtonType(ButtonType.RAISED);
-        button.setDepthLevel(DepthLevel.LEVEL1);
+		MFXButton button = new MFXButton("SHOW");
+		button.backgroundProperty().addListener((observable, oldValue, newValue) -> {
+			List<BackgroundFill> fills = newValue.getFills();
+			Paint[] colors = fills.stream().map(BackgroundFill::getFill).toArray(Paint[]::new);
+			System.out.println(Arrays.toString(colors));
+		});
+		button.setPrefSize(180, 36);
+		button.setButtonType(ButtonType.RAISED);
+		button.setDepthLevel(DepthLevel.LEVEL1);
 
-        button.setOnAction(event -> {
-                MFXButton hello = new MFXButton("Hello Button");
-                MFXPopup popup = new MFXPopup(hello);
-                popup.setPopupStyleableParent(stackPane);
-                popup.show(button, Alignment.of(HPos.LEFT, VPos.BOTTOM), -0, -0);
-        });
+		button.setOnAction(event -> {
+			MFXButton hello = new MFXButton("Hello Button");
+			MFXPopup popup = new MFXPopup(hello);
+			popup.setPopupStyleableParent(stackPane);
+			popup.show(button, Alignment.of(HPos.LEFT, VPos.BOTTOM), -0, -0);
+		});
 
-        stackPane.getChildren().add(button);
-        Scene scene = new Scene(stackPane, 800, 800);
-        primaryStage.setScene(scene);
-        primaryStage.show();
-    }
+		stackPane.getChildren().add(button);
+		Scene scene = new Scene(stackPane, 800, 800);
+		primaryStage.setScene(scene);
+		primaryStage.show();
+	}
 
-    private INotification createDummyNotification() {
-        MFXTextField label = MFXTextField.asLabel("Random Label n." + RandomUtils.random.nextInt());
-        label.setLeadingIcon(MFXFontIcon.getRandomIcon(32, ColorUtils.getRandomColor()));
-        label.setAlignment(Pos.CENTER_LEFT);
-        label.setMaxWidth(Double.MAX_VALUE);
-        HBox.setHgrow(label, Priority.ALWAYS);
+	private INotification createDummyNotification() {
+		MFXTextField label = MFXTextField.asLabel("Random Label n." + RandomUtils.random.nextInt());
+		label.setLeadingIcon(MFXFontIcon.getRandomIcon(32, ColorUtils.getRandomColor()));
+		label.setAlignment(Pos.CENTER_LEFT);
+		label.setMaxWidth(Double.MAX_VALUE);
+		HBox.setHgrow(label, Priority.ALWAYS);
 
-        MFXTextField time = MFXTextField.asLabel();
-        time.setAlignment(Pos.CENTER_RIGHT);
+		MFXTextField time = MFXTextField.asLabel();
+		time.setAlignment(Pos.CENTER_RIGHT);
 
-        HBox box = new HBox(label, time);
-        box.setMinSize(450, 100);
-        box.setStyle("-fx-background-color: white");
-        box.setAlignment(Pos.CENTER_LEFT);
-        MFXSimpleNotification notification = new MFXSimpleNotification(box);
-        notification.setOnUpdateElapsed((longElapsed, stringElapsed) -> Platform.runLater(() -> time.setText(stringElapsed)));
-        time.setText(notification.getTimeToStringConverter().apply(notification.getElapsedTime()));
-        box.setStyle("" +
-                "-fx-background-color: transparent;\n" +
-                "-fx-border-color: red");
-        return notification;
-    }
+		HBox box = new HBox(label, time);
+		box.setMinSize(450, 100);
+		box.setStyle("-fx-background-color: white");
+		box.setAlignment(Pos.CENTER_LEFT);
+		MFXSimpleNotification notification = new MFXSimpleNotification(box);
+		notification.setOnUpdateElapsed((longElapsed, stringElapsed) -> Platform.runLater(() -> time.setText(stringElapsed)));
+		time.setText(notification.getTimeToStringConverter().apply(notification.getElapsedTime()));
+		box.setStyle("" +
+				"-fx-background-color: transparent;\n" +
+				"-fx-border-color: red");
+		return notification;
+	}
 }

+ 42 - 42
demo/src/test/java/collections/TransformableListTest.java

@@ -15,55 +15,55 @@ import static org.junit.jupiter.api.Assertions.*;
 
 @ExtendWith(ApplicationExtension.class)
 public class TransformableListTest {
-    private final ObservableList<String> source = FXCollections.observableArrayList("A", "B", "C", "D", "E");
+	private final ObservableList<String> source = FXCollections.observableArrayList("A", "B", "C", "D", "E");
 
-    @Test
-    public void sortTest1() {
-        TransformableList<String> transformed = new TransformableList<>(source);
-        transformed.setComparator(Comparator.reverseOrder(), true);
+	@Test
+	public void sortTest1() {
+		TransformableList<String> transformed = new TransformableList<>(source);
+		transformed.setComparator(Comparator.reverseOrder(), true);
 
-        assertEquals(transformed.get(4), "A");
-        assertEquals(transformed.indexOf("E"), 0);
-        assertEquals(transformed.viewToSource(0), 4);
-        assertEquals(transformed.sourceToView(0), 4);
-    }
+		assertEquals(transformed.get(4), "A");
+		assertEquals(transformed.indexOf("E"), 0);
+		assertEquals(transformed.viewToSource(0), 4);
+		assertEquals(transformed.sourceToView(0), 4);
+	}
 
-    @Test
-    public void sortAndFilterTest1() {
-        TransformableList<String> transformed = new TransformableList<>(source);
-        transformed.setComparator(Comparator.reverseOrder(), true);
-        transformed.setPredicate(s -> s.equals("A") || s.equals("C") || s.equals("E"));
+	@Test
+	public void sortAndFilterTest1() {
+		TransformableList<String> transformed = new TransformableList<>(source);
+		transformed.setComparator(Comparator.reverseOrder(), true);
+		transformed.setPredicate(s -> s.equals("A") || s.equals("C") || s.equals("E"));
 
-        assertThrows(IndexOutOfBoundsException.class, () -> transformed.get(4));
-        assertEquals(transformed.get(1), "C");
-        assertEquals(transformed.indexOf("E"), 0);
-        assertEquals(transformed.viewToSource(1), 2);
-        assertEquals(transformed.sourceToView(1), -1);
-    }
+		assertThrows(IndexOutOfBoundsException.class, () -> transformed.get(4));
+		assertEquals(transformed.get(1), "C");
+		assertEquals(transformed.indexOf("E"), 0);
+		assertEquals(transformed.viewToSource(1), 2);
+		assertEquals(transformed.sourceToView(1), -1);
+	}
 
-    @Test
-    public void testJavaFX1() {
-        SortedList<String> sorted = new SortedList<>(source);
-        sorted.setComparator(Comparator.reverseOrder());
+	@Test
+	public void testJavaFX1() {
+		SortedList<String> sorted = new SortedList<>(source);
+		sorted.setComparator(Comparator.reverseOrder());
 
-        assertEquals(sorted.get(4), "A");
-        assertEquals(sorted.indexOf("E"), 0);
-        assertEquals(sorted.getSourceIndex(0), 4);
-        assertEquals(sorted.getViewIndex(0), 4);
-    }
+		assertEquals(sorted.get(4), "A");
+		assertEquals(sorted.indexOf("E"), 0);
+		assertEquals(sorted.getSourceIndex(0), 4);
+		assertEquals(sorted.getViewIndex(0), 4);
+	}
 
-    @Test
-    public void testJavaFX2() {
-        SortedList<String> sorted = new SortedList<>(source);
-        sorted.setComparator(Comparator.reverseOrder());
+	@Test
+	public void testJavaFX2() {
+		SortedList<String> sorted = new SortedList<>(source);
+		sorted.setComparator(Comparator.reverseOrder());
 
-        FilteredList<String> filtered = new FilteredList<>(sorted);
-        filtered.setPredicate(s -> s.equals("A") || s.equals("C") || s.equals("E"));
+		FilteredList<String> filtered = new FilteredList<>(sorted);
+		filtered.setPredicate(s -> s.equals("A") || s.equals("C") || s.equals("E"));
 
-        assertThrows(IndexOutOfBoundsException.class, () -> filtered.get(4));
-        assertEquals(filtered.get(1), "C");
-        assertEquals(filtered.indexOf("E"), 0);
-        assertEquals(filtered.getSourceIndex(1), 2);
-        assertTrue(filtered.getViewIndex(1) < 0);
-    }
+		assertThrows(IndexOutOfBoundsException.class, () -> filtered.get(4));
+		assertEquals(filtered.get(1), "C");
+		assertEquals(filtered.indexOf("E"), 0);
+		assertEquals(filtered.getSourceIndex(1), 2);
+		assertTrue(filtered.getViewIndex(1) < 0);
+	}
 }

+ 28 - 28
demo/src/test/java/combobox/ComboBoxTest.java

@@ -15,32 +15,32 @@ import java.util.stream.IntStream;
 
 public class ComboBoxTest extends Application {
 
-    @Override
-    public void start(Stage primaryStage) {
-        HBox hBox = new HBox(50);
-        hBox.setAlignment(Pos.TOP_CENTER);
-        hBox.setPadding(new Insets(20, 0, 0, 0));
-
-        ObservableList<String> s1 = FXCollections.observableArrayList();
-        ObservableList<String> s2 = FXCollections.observableArrayList();
-        ObservableList<String> s3 = FXCollections.observableArrayList();
-
-        IntStream.rangeClosed(0, 10).forEach(i -> s1.add("String " + i));
-        IntStream.rangeClosed(30, 40).forEach(i -> s2.add("String " + i));
-        IntStream.rangeClosed(55, 65).forEach(i -> s3.add("String " + i));
-
-        MFXFilterComboBox<String> c1 = new MFXFilterComboBox<>(s1);
-        MFXFilterComboBox<String> c2 = new MFXFilterComboBox<>(s2);
-        MFXFilterComboBox<String> c3 = new MFXFilterComboBox<>(s3);
-
-        c2.valueProperty().bind(c1.valueProperty());
-        c3.getSelectionModel().bindIndexBidirectional(c1.getSelectionModel());
-
-        hBox.getChildren().addAll(c1, c2, c3);
-        Scene scene = new Scene(hBox, 800, 800);
-        primaryStage.setScene(scene);
-        primaryStage.show();
-
-        ScenicView.show(scene);
-    }
+	@Override
+	public void start(Stage primaryStage) {
+		HBox hBox = new HBox(50);
+		hBox.setAlignment(Pos.TOP_CENTER);
+		hBox.setPadding(new Insets(20, 0, 0, 0));
+
+		ObservableList<String> s1 = FXCollections.observableArrayList();
+		ObservableList<String> s2 = FXCollections.observableArrayList();
+		ObservableList<String> s3 = FXCollections.observableArrayList();
+
+		IntStream.rangeClosed(0, 10).forEach(i -> s1.add("String " + i));
+		IntStream.rangeClosed(30, 40).forEach(i -> s2.add("String " + i));
+		IntStream.rangeClosed(55, 65).forEach(i -> s3.add("String " + i));
+
+		MFXFilterComboBox<String> c1 = new MFXFilterComboBox<>(s1);
+		MFXFilterComboBox<String> c2 = new MFXFilterComboBox<>(s2);
+		MFXFilterComboBox<String> c3 = new MFXFilterComboBox<>(s3);
+
+		c2.valueProperty().bind(c1.valueProperty());
+		c3.getSelectionModel().bindIndexBidirectional(c1.getSelectionModel());
+
+		hBox.getChildren().addAll(c1, c2, c3);
+		Scene scene = new Scene(hBox, 800, 800);
+		primaryStage.setScene(scene);
+		primaryStage.show();
+
+		ScenicView.show(scene);
+	}
 }

+ 83 - 83
demo/src/test/java/properties/SynchronizedBooleanTests.java

@@ -15,87 +15,87 @@ import static org.junit.jupiter.api.Assertions.*;
 
 @ExtendWith(ApplicationExtension.class)
 public class SynchronizedBooleanTests {
-    private final BooleanProperty booleanProperty = new SimpleBooleanProperty();
-
-    @BeforeEach
-    public void setUp() {
-        booleanProperty.set(false);
-    }
-
-    @Test
-    public void testSync() {
-        SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
-        synced.setAndWait(true, booleanProperty);
-        booleanProperty.set(true);
-        assertTrue(synced.get());
-        assertTrue(booleanProperty.get());
-    }
-
-    @Test
-    public void testBind1() {
-        AtomicBoolean changed = new AtomicBoolean(false);
-        SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
-        synced.bind(booleanProperty);
-        synced.addListener((observable, oldValue, newValue) -> changed.set(true));
-        booleanProperty.set(true);
-        assertTrue(changed.get());
-    }
-
-    @Test
-    public void testBind2() {
-        Throwable th = null;
-
-        SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
-        synced.bind(booleanProperty);
-
-        try {
-            synced.setAndWait(true, booleanProperty);
-        } catch (Exception ex) {
-            th = ex;
-        }
-
-        assertNotNull(th);
-        assertEquals("A bound value cannot be set!", th.getMessage());
-        assertFalse(synced.isWaiting());
-    }
-
-    @Test
-    public void testBindBidirectional() {
-        AtomicBoolean aValue = new AtomicBoolean();
-        AtomicBoolean bValue = new AtomicBoolean();
-
-        SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
-        synced.bindBidirectional(booleanProperty);
-
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        booleanProperty.set(true);
-        assertTrue(aValue.get());
-        assertTrue(booleanProperty.get());
-        synced.set(false); // Need to reset in order to fire change event
-
-        ExecutionUtils.executeWhen(
-                booleanProperty,
-                (oldValue, newValue) -> bValue.set(newValue),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set(true);
-        assertTrue(bValue.get());
-        assertTrue(synced.get());
-    }
-
-    @Test
-    public void testFailSync() {
-        SynchronizedBooleanProperty synced1 = new SynchronizedBooleanProperty();
-        SynchronizedBooleanProperty synced2 = new SynchronizedBooleanProperty();
-        synced1.setAndWait(true, synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(true, synced1));
-    }
+	private final BooleanProperty booleanProperty = new SimpleBooleanProperty();
+
+	@BeforeEach
+	public void setUp() {
+		booleanProperty.set(false);
+	}
+
+	@Test
+	public void testSync() {
+		SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
+		synced.setAndWait(true, booleanProperty);
+		booleanProperty.set(true);
+		assertTrue(synced.get());
+		assertTrue(booleanProperty.get());
+	}
+
+	@Test
+	public void testBind1() {
+		AtomicBoolean changed = new AtomicBoolean(false);
+		SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
+		synced.bind(booleanProperty);
+		synced.addListener((observable, oldValue, newValue) -> changed.set(true));
+		booleanProperty.set(true);
+		assertTrue(changed.get());
+	}
+
+	@Test
+	public void testBind2() {
+		Throwable th = null;
+
+		SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
+		synced.bind(booleanProperty);
+
+		try {
+			synced.setAndWait(true, booleanProperty);
+		} catch (Exception ex) {
+			th = ex;
+		}
+
+		assertNotNull(th);
+		assertEquals("A bound value cannot be set!", th.getMessage());
+		assertFalse(synced.isWaiting());
+	}
+
+	@Test
+	public void testBindBidirectional() {
+		AtomicBoolean aValue = new AtomicBoolean();
+		AtomicBoolean bValue = new AtomicBoolean();
+
+		SynchronizedBooleanProperty synced = new SynchronizedBooleanProperty();
+		synced.bindBidirectional(booleanProperty);
+
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		booleanProperty.set(true);
+		assertTrue(aValue.get());
+		assertTrue(booleanProperty.get());
+		synced.set(false); // Need to reset in order to fire change event
+
+		ExecutionUtils.executeWhen(
+				booleanProperty,
+				(oldValue, newValue) -> bValue.set(newValue),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set(true);
+		assertTrue(bValue.get());
+		assertTrue(synced.get());
+	}
+
+	@Test
+	public void testFailSync() {
+		SynchronizedBooleanProperty synced1 = new SynchronizedBooleanProperty();
+		SynchronizedBooleanProperty synced2 = new SynchronizedBooleanProperty();
+		synced1.setAndWait(true, synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(true, synced1));
+	}
 }

+ 55 - 55
demo/src/test/java/properties/SynchronizedDoubleTests.java

@@ -16,67 +16,67 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 
 @ExtendWith(ApplicationExtension.class)
 public class SynchronizedDoubleTests {
-    private final DoubleProperty doubleProperty = new SimpleDoubleProperty();
+	private final DoubleProperty doubleProperty = new SimpleDoubleProperty();
 
-    @BeforeEach
-    public void setUp() {
-        doubleProperty.set(0.0);
-    }
+	@BeforeEach
+	public void setUp() {
+		doubleProperty.set(0.0);
+	}
 
-    @Test
-    public void testSync() {
-        SynchronizedDoubleProperty synced = new SynchronizedDoubleProperty();
-        synced.setAndWait(9.9, doubleProperty);
-        doubleProperty.set(7.5);
-        assertEquals(9.9, synced.get());
-        assertEquals(7.5, doubleProperty.get());
-    }
+	@Test
+	public void testSync() {
+		SynchronizedDoubleProperty synced = new SynchronizedDoubleProperty();
+		synced.setAndWait(9.9, doubleProperty);
+		doubleProperty.set(7.5);
+		assertEquals(9.9, synced.get());
+		assertEquals(7.5, doubleProperty.get());
+	}
 
-    @Test
-    public void testBind() {
-        SynchronizedDoubleProperty synced = new SynchronizedDoubleProperty();
-        synced.bind(doubleProperty);
-        doubleProperty.set(8.8);
-        assertEquals(8.8, synced.get());
-        assertEquals(8.8, doubleProperty.get());
-    }
+	@Test
+	public void testBind() {
+		SynchronizedDoubleProperty synced = new SynchronizedDoubleProperty();
+		synced.bind(doubleProperty);
+		doubleProperty.set(8.8);
+		assertEquals(8.8, synced.get());
+		assertEquals(8.8, doubleProperty.get());
+	}
 
-    @Test
-    public void testBindBidirectional() {
-        AtomicReference<Double> aValue = new AtomicReference<>();
-        AtomicReference<Double> bValue = new AtomicReference<>();
+	@Test
+	public void testBindBidirectional() {
+		AtomicReference<Double> aValue = new AtomicReference<>();
+		AtomicReference<Double> bValue = new AtomicReference<>();
 
-        SynchronizedDoubleProperty synced = new SynchronizedDoubleProperty();
-        synced.bindBidirectional(doubleProperty);
+		SynchronizedDoubleProperty synced = new SynchronizedDoubleProperty();
+		synced.bindBidirectional(doubleProperty);
 
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue.doubleValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        doubleProperty.set(8.5);
-        assertEquals(8.5, aValue.get());
-        assertEquals(8.5, doubleProperty.get());
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue.doubleValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		doubleProperty.set(8.5);
+		assertEquals(8.5, aValue.get());
+		assertEquals(8.5, doubleProperty.get());
 
-        ExecutionUtils.executeWhen(
-                doubleProperty,
-                (oldValue, newValue) -> bValue.set(newValue.doubleValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set(7.5);
-        assertEquals(7.5, bValue.get());
-        assertEquals(7.5, synced.get());
-    }
+		ExecutionUtils.executeWhen(
+				doubleProperty,
+				(oldValue, newValue) -> bValue.set(newValue.doubleValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set(7.5);
+		assertEquals(7.5, bValue.get());
+		assertEquals(7.5, synced.get());
+	}
 
-    @Test
-    public void testFailSync() {
-        SynchronizedDoubleProperty synced1 = new SynchronizedDoubleProperty();
-        SynchronizedDoubleProperty synced2 = new SynchronizedDoubleProperty();
-        synced1.setAndWait(0.36, synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(0.56, synced1));
-    }
+	@Test
+	public void testFailSync() {
+		SynchronizedDoubleProperty synced1 = new SynchronizedDoubleProperty();
+		SynchronizedDoubleProperty synced2 = new SynchronizedDoubleProperty();
+		synced1.setAndWait(0.36, synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(0.56, synced1));
+	}
 }

+ 55 - 55
demo/src/test/java/properties/SynchronizedFloatTests.java

@@ -13,67 +13,67 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 public class SynchronizedFloatTests {
-    private final FloatProperty floatProperty = new SimpleFloatProperty();
+	private final FloatProperty floatProperty = new SimpleFloatProperty();
 
-    @BeforeEach
-    public void setUp() {
-        floatProperty.set(0.0F);
-    }
+	@BeforeEach
+	public void setUp() {
+		floatProperty.set(0.0F);
+	}
 
-    @Test
-    public void testSync() {
-        SynchronizedFloatProperty synced = new SynchronizedFloatProperty();
-        synced.setAndWait(0.9F, floatProperty);
-        floatProperty.set(0.7F);
-        assertEquals(0.9F, synced.get());
-        assertEquals(0.7F, floatProperty.get());
-    }
+	@Test
+	public void testSync() {
+		SynchronizedFloatProperty synced = new SynchronizedFloatProperty();
+		synced.setAndWait(0.9F, floatProperty);
+		floatProperty.set(0.7F);
+		assertEquals(0.9F, synced.get());
+		assertEquals(0.7F, floatProperty.get());
+	}
 
-    @Test
-    public void testBind() {
-        SynchronizedFloatProperty synced = new SynchronizedFloatProperty();
-        synced.bind(floatProperty);
-        floatProperty.set(0.8F);
-        assertEquals(0.8F, synced.get());
-        assertEquals(0.8F, floatProperty.get());
-    }
+	@Test
+	public void testBind() {
+		SynchronizedFloatProperty synced = new SynchronizedFloatProperty();
+		synced.bind(floatProperty);
+		floatProperty.set(0.8F);
+		assertEquals(0.8F, synced.get());
+		assertEquals(0.8F, floatProperty.get());
+	}
 
-    @Test
-    public void testBindBidirectional() {
-        AtomicReference<Float> aValue = new AtomicReference<>();
-        AtomicReference<Float> bValue = new AtomicReference<>();
+	@Test
+	public void testBindBidirectional() {
+		AtomicReference<Float> aValue = new AtomicReference<>();
+		AtomicReference<Float> bValue = new AtomicReference<>();
 
-        SynchronizedFloatProperty synced = new SynchronizedFloatProperty();
-        synced.bindBidirectional(floatProperty);
+		SynchronizedFloatProperty synced = new SynchronizedFloatProperty();
+		synced.bindBidirectional(floatProperty);
 
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue.floatValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        floatProperty.set(0.8F);
-        assertEquals(0.8F, aValue.get());
-        assertEquals(0.8F, floatProperty.get());
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue.floatValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		floatProperty.set(0.8F);
+		assertEquals(0.8F, aValue.get());
+		assertEquals(0.8F, floatProperty.get());
 
-        ExecutionUtils.executeWhen(
-                floatProperty,
-                (oldValue, newValue) -> bValue.set(newValue.floatValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set(0.7F);
-        assertEquals(0.7F, bValue.get());
-        assertEquals(0.7F, synced.get());
-    }
+		ExecutionUtils.executeWhen(
+				floatProperty,
+				(oldValue, newValue) -> bValue.set(newValue.floatValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set(0.7F);
+		assertEquals(0.7F, bValue.get());
+		assertEquals(0.7F, synced.get());
+	}
 
-    @Test
-    public void testFailSync() {
-        SynchronizedFloatProperty synced1 = new SynchronizedFloatProperty();
-        SynchronizedFloatProperty synced2 = new SynchronizedFloatProperty();
-        synced1.setAndWait(0.1F, synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(0.2F, synced1));
-    }
+	@Test
+	public void testFailSync() {
+		SynchronizedFloatProperty synced1 = new SynchronizedFloatProperty();
+		SynchronizedFloatProperty synced2 = new SynchronizedFloatProperty();
+		synced1.setAndWait(0.1F, synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(0.2F, synced1));
+	}
 }

+ 113 - 113
demo/src/test/java/properties/SynchronizedIntegerTests.java

@@ -15,117 +15,117 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 public class SynchronizedIntegerTests {
-    private final IntegerProperty integerProperty = new SimpleIntegerProperty();
-
-    @BeforeEach
-    public void setUp() {
-        integerProperty.set(0);
-    }
-
-    @Test
-    public void testSync() {
-        SynchronizedIntegerProperty synced = new SynchronizedIntegerProperty();
-        synced.setAndWait(9, integerProperty);
-        integerProperty.set(7);
-        assertEquals(9, synced.get());
-        assertEquals(7, integerProperty.get());
-    }
-
-    @Test
-    public void testBind() {
-        SynchronizedIntegerProperty synced = new SynchronizedIntegerProperty();
-        synced.bind(integerProperty);
-        integerProperty.set(8);
-        assertEquals(8, synced.get());
-        assertEquals(8, integerProperty.get());
-    }
-
-    @Test
-    public void testBindBidirectional() {
-        AtomicInteger aValue = new AtomicInteger();
-        AtomicInteger bValue = new AtomicInteger();
-
-        SynchronizedIntegerProperty synced = new SynchronizedIntegerProperty();
-        synced.bindBidirectional(integerProperty);
-
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue.intValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        integerProperty.set(8);
-        assertEquals(8, aValue.get());
-        assertEquals(8, integerProperty.get());
-
-        ExecutionUtils.executeWhen(
-                integerProperty,
-                (oldValue, newValue) -> bValue.set(newValue.intValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set(7);
-        assertEquals(7, bValue.get());
-        assertEquals(7, synced.get());
-    }
-
-    @Test
-    public void testFailSync() {
-        SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
-        SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
-        synced1.setAndWait(1, synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(2, synced1));
-    }
-
-    @Test
-    public void testChain1() {
-        AtomicInteger a1 = new AtomicInteger();
-        AtomicInteger a2 = new AtomicInteger();
-        AtomicInteger a3 = new AtomicInteger();
-
-        SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
-        SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
-        synced1.addListener((observable, oldValue, newValue) -> {
-            a1.set(newValue.intValue());
-            System.out.println(newValue);
-        });
-        synced2.addListener((observable, oldValue, newValue) -> {
-            a2.set(newValue.intValue());
-            System.out.println(newValue);
-        });
-        integerProperty.addListener(new ChangeListener<>() {
-            @Override
-            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
-                a3.set(newValue.intValue());
-                System.out.println(newValue);
-                integerProperty.removeListener(this);
-            }
-        });
-
-        synced1.setAndWait(8, synced2);
-        synced2.setAndWait(10, integerProperty);
-        integerProperty.set(12);
-
-        assertEquals(8, a1.get());
-        assertEquals(10, a2.get());
-        assertEquals(12, a3.get());
-    }
-
-    @Test
-    public void testChain2() {
-        SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
-        SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
-        synced1.setAndWait(8, synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(10, synced1));
-    }
-
-    @Test
-    public void testOverrideWait() {
-        SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
-        SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
-        synced1.setAndWait(8, synced2);
-        assertThrows(IllegalStateException.class, () -> synced1.setAndWait(10, integerProperty));
-    }
+	private final IntegerProperty integerProperty = new SimpleIntegerProperty();
+
+	@BeforeEach
+	public void setUp() {
+		integerProperty.set(0);
+	}
+
+	@Test
+	public void testSync() {
+		SynchronizedIntegerProperty synced = new SynchronizedIntegerProperty();
+		synced.setAndWait(9, integerProperty);
+		integerProperty.set(7);
+		assertEquals(9, synced.get());
+		assertEquals(7, integerProperty.get());
+	}
+
+	@Test
+	public void testBind() {
+		SynchronizedIntegerProperty synced = new SynchronizedIntegerProperty();
+		synced.bind(integerProperty);
+		integerProperty.set(8);
+		assertEquals(8, synced.get());
+		assertEquals(8, integerProperty.get());
+	}
+
+	@Test
+	public void testBindBidirectional() {
+		AtomicInteger aValue = new AtomicInteger();
+		AtomicInteger bValue = new AtomicInteger();
+
+		SynchronizedIntegerProperty synced = new SynchronizedIntegerProperty();
+		synced.bindBidirectional(integerProperty);
+
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue.intValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		integerProperty.set(8);
+		assertEquals(8, aValue.get());
+		assertEquals(8, integerProperty.get());
+
+		ExecutionUtils.executeWhen(
+				integerProperty,
+				(oldValue, newValue) -> bValue.set(newValue.intValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set(7);
+		assertEquals(7, bValue.get());
+		assertEquals(7, synced.get());
+	}
+
+	@Test
+	public void testFailSync() {
+		SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
+		SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
+		synced1.setAndWait(1, synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(2, synced1));
+	}
+
+	@Test
+	public void testChain1() {
+		AtomicInteger a1 = new AtomicInteger();
+		AtomicInteger a2 = new AtomicInteger();
+		AtomicInteger a3 = new AtomicInteger();
+
+		SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
+		SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
+		synced1.addListener((observable, oldValue, newValue) -> {
+			a1.set(newValue.intValue());
+			System.out.println(newValue);
+		});
+		synced2.addListener((observable, oldValue, newValue) -> {
+			a2.set(newValue.intValue());
+			System.out.println(newValue);
+		});
+		integerProperty.addListener(new ChangeListener<>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				a3.set(newValue.intValue());
+				System.out.println(newValue);
+				integerProperty.removeListener(this);
+			}
+		});
+
+		synced1.setAndWait(8, synced2);
+		synced2.setAndWait(10, integerProperty);
+		integerProperty.set(12);
+
+		assertEquals(8, a1.get());
+		assertEquals(10, a2.get());
+		assertEquals(12, a3.get());
+	}
+
+	@Test
+	public void testChain2() {
+		SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
+		SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
+		synced1.setAndWait(8, synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(10, synced1));
+	}
+
+	@Test
+	public void testOverrideWait() {
+		SynchronizedIntegerProperty synced1 = new SynchronizedIntegerProperty();
+		SynchronizedIntegerProperty synced2 = new SynchronizedIntegerProperty();
+		synced1.setAndWait(8, synced2);
+		assertThrows(IllegalStateException.class, () -> synced1.setAndWait(10, integerProperty));
+	}
 }

+ 55 - 55
demo/src/test/java/properties/SynchronizedLongTests.java

@@ -13,67 +13,67 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 public class SynchronizedLongTests {
-    private final LongProperty longProperty = new SimpleLongProperty();
+	private final LongProperty longProperty = new SimpleLongProperty();
 
-    @BeforeEach
-    public void setUp() {
-        longProperty.set(0L);
-    }
+	@BeforeEach
+	public void setUp() {
+		longProperty.set(0L);
+	}
 
-    @Test
-    public void testSync() {
-        SynchronizedLongProperty synced = new SynchronizedLongProperty();
-        synced.setAndWait(9L, longProperty);
-        longProperty.set(7L);
-        assertEquals(9L, synced.get());
-        assertEquals(7L, longProperty.get());
-    }
+	@Test
+	public void testSync() {
+		SynchronizedLongProperty synced = new SynchronizedLongProperty();
+		synced.setAndWait(9L, longProperty);
+		longProperty.set(7L);
+		assertEquals(9L, synced.get());
+		assertEquals(7L, longProperty.get());
+	}
 
-    @Test
-    public void testBind() {
-        SynchronizedLongProperty synced = new SynchronizedLongProperty();
-        synced.bind(longProperty);
-        longProperty.set(8L);
-        assertEquals(8L, synced.get());
-        assertEquals(8L, longProperty.get());
-    }
+	@Test
+	public void testBind() {
+		SynchronizedLongProperty synced = new SynchronizedLongProperty();
+		synced.bind(longProperty);
+		longProperty.set(8L);
+		assertEquals(8L, synced.get());
+		assertEquals(8L, longProperty.get());
+	}
 
-    @Test
-    public void testBindBidirectional() {
-        AtomicLong aValue = new AtomicLong();
-        AtomicLong bValue = new AtomicLong();
+	@Test
+	public void testBindBidirectional() {
+		AtomicLong aValue = new AtomicLong();
+		AtomicLong bValue = new AtomicLong();
 
-        SynchronizedLongProperty synced = new SynchronizedLongProperty();
-        synced.bindBidirectional(longProperty);
+		SynchronizedLongProperty synced = new SynchronizedLongProperty();
+		synced.bindBidirectional(longProperty);
 
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue.longValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        longProperty.set(8L);
-        assertEquals(8L, aValue.get());
-        assertEquals(8L, longProperty.get());
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue.longValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		longProperty.set(8L);
+		assertEquals(8L, aValue.get());
+		assertEquals(8L, longProperty.get());
 
-        ExecutionUtils.executeWhen(
-                longProperty,
-                (oldValue, newValue) -> bValue.set(newValue.longValue()),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set(7L);
-        assertEquals(7L, bValue.get());
-        assertEquals(7L, synced.get());
-    }
+		ExecutionUtils.executeWhen(
+				longProperty,
+				(oldValue, newValue) -> bValue.set(newValue.longValue()),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set(7L);
+		assertEquals(7L, bValue.get());
+		assertEquals(7L, synced.get());
+	}
 
-    @Test
-    public void testFailSync() {
-        SynchronizedLongProperty synced1 = new SynchronizedLongProperty();
-        SynchronizedLongProperty synced2 = new SynchronizedLongProperty();
-        synced1.setAndWait(1L, synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(2L, synced1));
-    }
+	@Test
+	public void testFailSync() {
+		SynchronizedLongProperty synced1 = new SynchronizedLongProperty();
+		SynchronizedLongProperty synced2 = new SynchronizedLongProperty();
+		synced1.setAndWait(1L, synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(2L, synced1));
+	}
 }

+ 55 - 56
demo/src/test/java/properties/SynchronizedObjectTests.java

@@ -10,71 +10,70 @@ import org.junit.jupiter.api.Test;
 
 import java.util.concurrent.atomic.AtomicReference;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 public class SynchronizedObjectTests {
-    private final ObjectProperty<SimplePerson> objectProperty = new SimpleObjectProperty<>();
+	private final ObjectProperty<SimplePerson> objectProperty = new SimpleObjectProperty<>();
 
-    @BeforeEach
-    public void setUp() {
-        objectProperty.set(null);
-    }
+	@BeforeEach
+	public void setUp() {
+		objectProperty.set(null);
+	}
 
-    @Test
-    public void testSync() {
-        SynchronizedObjectProperty<SimplePerson> synced = new SynchronizedObjectProperty<>();
-        synced.setAndWait(new SimplePerson("Jack"), objectProperty);
-        objectProperty.set(new SimplePerson("Rose"));
-        assertEquals("Jack", synced.get().getName());
-        assertEquals("Rose", objectProperty.get().getName());
-    }
+	@Test
+	public void testSync() {
+		SynchronizedObjectProperty<SimplePerson> synced = new SynchronizedObjectProperty<>();
+		synced.setAndWait(new SimplePerson("Jack"), objectProperty);
+		objectProperty.set(new SimplePerson("Rose"));
+		assertEquals("Jack", synced.get().getName());
+		assertEquals("Rose", objectProperty.get().getName());
+	}
 
-    @Test
-    public void testBind() {
-        SynchronizedObjectProperty<SimplePerson> synced = new SynchronizedObjectProperty<>();
-        synced.bind(objectProperty);
-        objectProperty.set(new SimplePerson("Mark"));
-        assertEquals("Mark", synced.get().getName());
-        assertEquals("Mark", objectProperty.get().getName());
-    }
+	@Test
+	public void testBind() {
+		SynchronizedObjectProperty<SimplePerson> synced = new SynchronizedObjectProperty<>();
+		synced.bind(objectProperty);
+		objectProperty.set(new SimplePerson("Mark"));
+		assertEquals("Mark", synced.get().getName());
+		assertEquals("Mark", objectProperty.get().getName());
+	}
 
-    @Test
-    public void testBindBidirectional() {
-        AtomicReference<SimplePerson> aValue = new AtomicReference<>();
-        AtomicReference<SimplePerson> bValue = new AtomicReference<>();
+	@Test
+	public void testBindBidirectional() {
+		AtomicReference<SimplePerson> aValue = new AtomicReference<>();
+		AtomicReference<SimplePerson> bValue = new AtomicReference<>();
 
-        SynchronizedObjectProperty<SimplePerson> synced = new SynchronizedObjectProperty<>();
-        synced.bindBidirectional(objectProperty);
+		SynchronizedObjectProperty<SimplePerson> synced = new SynchronizedObjectProperty<>();
+		synced.bindBidirectional(objectProperty);
 
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        objectProperty.set(new SimplePerson("Jack"));
-        assertEquals("Jack", aValue.get().getName());
-        assertEquals("Jack", objectProperty.get().getName());
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		objectProperty.set(new SimplePerson("Jack"));
+		assertEquals("Jack", aValue.get().getName());
+		assertEquals("Jack", objectProperty.get().getName());
 
-        ExecutionUtils.executeWhen(
-                objectProperty,
-                (oldValue, newValue) -> bValue.set(newValue),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set(new SimplePerson("Rose"));
-        assertEquals("Rose", bValue.get().getName());
-        assertEquals("Rose", synced.get().getName());
-    }
+		ExecutionUtils.executeWhen(
+				objectProperty,
+				(oldValue, newValue) -> bValue.set(newValue),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set(new SimplePerson("Rose"));
+		assertEquals("Rose", bValue.get().getName());
+		assertEquals("Rose", synced.get().getName());
+	}
 
-    @Test
-    public void testFailSync() {
-        SynchronizedObjectProperty<SimplePerson> synced1 = new SynchronizedObjectProperty<>();
-        SynchronizedObjectProperty<SimplePerson> synced2 = new SynchronizedObjectProperty<>();
-        synced1.setAndWait(new SimplePerson("Mark"), synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(new SimplePerson("Leia"), synced1));
-    }
+	@Test
+	public void testFailSync() {
+		SynchronizedObjectProperty<SimplePerson> synced1 = new SynchronizedObjectProperty<>();
+		SynchronizedObjectProperty<SimplePerson> synced2 = new SynchronizedObjectProperty<>();
+		synced1.setAndWait(new SimplePerson("Mark"), synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait(new SimplePerson("Leia"), synced1));
+	}
 }

+ 55 - 55
demo/src/test/java/properties/SynchronizedStringTests.java

@@ -13,67 +13,67 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 public class SynchronizedStringTests {
-    private final StringProperty stringProperty = new SimpleStringProperty();
+	private final StringProperty stringProperty = new SimpleStringProperty();
 
-    @BeforeEach
-    public void setUp() {
-        stringProperty.set(null);
-    }
+	@BeforeEach
+	public void setUp() {
+		stringProperty.set(null);
+	}
 
-    @Test
-    public void testSync() {
-        SynchronizedStringProperty synced = new SynchronizedStringProperty();
-        synced.setAndWait("SString", stringProperty);
-        stringProperty.set("PString");
-        assertEquals("SString", synced.get());
-        assertEquals("PString", stringProperty.get());
-    }
+	@Test
+	public void testSync() {
+		SynchronizedStringProperty synced = new SynchronizedStringProperty();
+		synced.setAndWait("SString", stringProperty);
+		stringProperty.set("PString");
+		assertEquals("SString", synced.get());
+		assertEquals("PString", stringProperty.get());
+	}
 
-    @Test
-    public void testBind() {
-        SynchronizedStringProperty synced = new SynchronizedStringProperty();
-        synced.bind(stringProperty);
-        stringProperty.set("BString");
-        assertEquals("BString", synced.get());
-        assertEquals("BString", stringProperty.get());
-    }
+	@Test
+	public void testBind() {
+		SynchronizedStringProperty synced = new SynchronizedStringProperty();
+		synced.bind(stringProperty);
+		stringProperty.set("BString");
+		assertEquals("BString", synced.get());
+		assertEquals("BString", stringProperty.get());
+	}
 
-    @Test
-    public void testBindBidirectional() {
-        AtomicReference<String> aValue = new AtomicReference<>();
-        AtomicReference<String> bValue = new AtomicReference<>();
+	@Test
+	public void testBindBidirectional() {
+		AtomicReference<String> aValue = new AtomicReference<>();
+		AtomicReference<String> bValue = new AtomicReference<>();
 
-        SynchronizedStringProperty synced = new SynchronizedStringProperty();
-        synced.bindBidirectional(stringProperty);
+		SynchronizedStringProperty synced = new SynchronizedStringProperty();
+		synced.bindBidirectional(stringProperty);
 
-        ExecutionUtils.executeWhen(
-                synced,
-                (oldValue, newValue) -> aValue.set(newValue),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        stringProperty.set("PString");
-        assertEquals("PString", aValue.get());
-        assertEquals("PString", stringProperty.get());
+		ExecutionUtils.executeWhen(
+				synced,
+				(oldValue, newValue) -> aValue.set(newValue),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		stringProperty.set("PString");
+		assertEquals("PString", aValue.get());
+		assertEquals("PString", stringProperty.get());
 
-        ExecutionUtils.executeWhen(
-                stringProperty,
-                (oldValue, newValue) -> bValue.set(newValue),
-                false,
-                (oldValue, newValue) -> newValue != null,
-                true
-        );
-        synced.set("SString");
-        assertEquals("SString", bValue.get());
-        assertEquals("SString", synced.get());
-    }
+		ExecutionUtils.executeWhen(
+				stringProperty,
+				(oldValue, newValue) -> bValue.set(newValue),
+				false,
+				(oldValue, newValue) -> newValue != null,
+				true
+		);
+		synced.set("SString");
+		assertEquals("SString", bValue.get());
+		assertEquals("SString", synced.get());
+	}
 
-    @Test
-    public void testFailSync() {
-        SynchronizedStringProperty synced1 = new SynchronizedStringProperty();
-        SynchronizedStringProperty synced2 = new SynchronizedStringProperty();
-        synced1.setAndWait("SS1", synced2);
-        assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait("SS2", synced1));
-    }
+	@Test
+	public void testFailSync() {
+		SynchronizedStringProperty synced1 = new SynchronizedStringProperty();
+		SynchronizedStringProperty synced2 = new SynchronizedStringProperty();
+		synced1.setAndWait("SS1", synced2);
+		assertThrows(IllegalArgumentException.class, () -> synced2.setAndWait("SS2", synced1));
+	}
 }

+ 102 - 102
demo/src/test/java/prototipes/FloatingTextPrototype.java

@@ -19,117 +19,117 @@ import javafx.scene.layout.VBox;
 import javafx.scene.transform.Scale;
 
 public class FloatingTextPrototype extends Labeled {
-    private final StringProperty promptText = new SimpleStringProperty("Floating Text");
+	private final StringProperty promptText = new SimpleStringProperty("Floating Text");
 
-    public FloatingTextPrototype() {
-        this("");
-    }
+	public FloatingTextPrototype() {
+		this("");
+	}
 
-    public FloatingTextPrototype(String text) {
-        this(text, null);
-    }
+	public FloatingTextPrototype(String text) {
+		this(text, null);
+	}
 
-    public FloatingTextPrototype(String text, Node graphic) {
-        super(text, graphic);
-        initialize();
-    }
+	public FloatingTextPrototype(String text, Node graphic) {
+		super(text, graphic);
+		initialize();
+	}
 
-    private void initialize() {
-        setPadding(InsetsFactory.of(5, 3, 5, 3));
-    }
+	private void initialize() {
+		setPadding(InsetsFactory.of(5, 3, 5, 3));
+	}
 
-    public String getPromptText() {
-        return promptText.get();
-    }
+	public String getPromptText() {
+		return promptText.get();
+	}
 
-    public StringProperty promptTextProperty() {
-        return promptText;
-    }
+	public StringProperty promptTextProperty() {
+		return promptText;
+	}
 
-    public void setPromptText(String promptText) {
-        this.promptText.set(promptText);
-    }
+	public void setPromptText(String promptText) {
+		this.promptText.set(promptText);
+	}
 
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new FloatingTextPrototypeSkin(this);
-    }
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new FloatingTextPrototypeSkin(this);
+	}
 }
 
 class FloatingTextPrototypeSkin extends SkinBase<FloatingTextPrototype> {
-    private final VBox container;
-    private final BoundLabel text;
-    private final Label promptText;
-
-    private final double scaleMultiplier = 0.85;
-    private final Scale scale = new Scale(1, 1, 0, 0);
-
-    private boolean floating = true;
-
-    public FloatingTextPrototypeSkin(FloatingTextPrototype control) {
-        super(control);
-
-        text = new BoundLabel(control);
-        text.setStyle("-fx-border-color: red");
-
-        promptText = new Label("Look! It's floating!");
-        promptText.setStyle("-fx-border-color: blue");
-        promptText.getTransforms().add(scale);
-
-        container = new VBox(promptText, text);
-        container.setAlignment(Pos.CENTER_LEFT);
-        getChildren().setAll(container);
-
-        setBehavior();
-    }
-
-    private void setBehavior() {
-        FloatingTextPrototype control = getSkinnable();
-
-        control.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
-            if (floating) {
-                double promptH = promptText.getHeight();
-                double y = (control.getHeight() / 2) - (promptH / 2) + snappedTopInset();
-                double translateY = y - promptText.getBoundsInParent().getMinY();
-                double mul = scale.getY();
-                ParallelBuilder.build()
-                        .add(
-                                ConsumerTransition.of(frac -> promptText.setTranslateY((translateY / 2) * frac * mul), 250)
-                                        .setOnFinishedFluent(end -> promptText.setTranslateY(snapPositionY(promptText.getTranslateY())))
-                                        .setInterpolatorFluent(Interpolators.INTERPOLATOR_V1)
-                        )
-                        .add(
-                                KeyFrames.of(250, scale.xProperty(), 1, Interpolators.INTERPOLATOR_V1),
-                                KeyFrames.of(250, scale.yProperty(), 1, Interpolators.INTERPOLATOR_V1)
-                        )
-                        .setOnFinished(end -> System.out.println("Y: " + promptText.getBoundsInParent().getMinY()))
-                        .getAnimation().play();
-                floating = false;
-            } else {
-                double initialTranslateY = promptText.getTranslateY();
-                ParallelBuilder.build()
-                        .add(
-                                ConsumerTransition.of(frac -> promptText.setTranslateY(initialTranslateY - (initialTranslateY * frac)), 250)
-                                        .setInterpolatorFluent(Interpolators.INTERPOLATOR_V1)
-                        )
-                        .add(
-                                KeyFrames.of(250, scale.xProperty(), scaleMultiplier, Interpolators.INTERPOLATOR_V1),
-                                KeyFrames.of(250, scale.yProperty(), scaleMultiplier, Interpolators.INTERPOLATOR_V1)
-                        )
-                        .setOnFinished(end -> System.out.println("Scaled Y: " + promptText.getBoundsInParent().getMinY()))
-                        .getAnimation().play();
-                floating = true;
-            }
-        });
-    }
-
-    @Override
-    protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        return getSkinnable().prefWidth(-1);
-    }
-
-    @Override
-    protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
-        return getSkinnable().prefHeight(-1);
-    }
+	private final VBox container;
+	private final BoundLabel text;
+	private final Label promptText;
+
+	private final double scaleMultiplier = 0.85;
+	private final Scale scale = new Scale(1, 1, 0, 0);
+
+	private boolean floating = true;
+
+	public FloatingTextPrototypeSkin(FloatingTextPrototype control) {
+		super(control);
+
+		text = new BoundLabel(control);
+		text.setStyle("-fx-border-color: red");
+
+		promptText = new Label("Look! It's floating!");
+		promptText.setStyle("-fx-border-color: blue");
+		promptText.getTransforms().add(scale);
+
+		container = new VBox(promptText, text);
+		container.setAlignment(Pos.CENTER_LEFT);
+		getChildren().setAll(container);
+
+		setBehavior();
+	}
+
+	private void setBehavior() {
+		FloatingTextPrototype control = getSkinnable();
+
+		control.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
+			if (floating) {
+				double promptH = promptText.getHeight();
+				double y = (control.getHeight() / 2) - (promptH / 2) + snappedTopInset();
+				double translateY = y - promptText.getBoundsInParent().getMinY();
+				double mul = scale.getY();
+				ParallelBuilder.build()
+						.add(
+								ConsumerTransition.of(frac -> promptText.setTranslateY((translateY / 2) * frac * mul), 250)
+										.setOnFinishedFluent(end -> promptText.setTranslateY(snapPositionY(promptText.getTranslateY())))
+										.setInterpolatorFluent(Interpolators.INTERPOLATOR_V1)
+						)
+						.add(
+								KeyFrames.of(250, scale.xProperty(), 1, Interpolators.INTERPOLATOR_V1),
+								KeyFrames.of(250, scale.yProperty(), 1, Interpolators.INTERPOLATOR_V1)
+						)
+						.setOnFinished(end -> System.out.println("Y: " + promptText.getBoundsInParent().getMinY()))
+						.getAnimation().play();
+				floating = false;
+			} else {
+				double initialTranslateY = promptText.getTranslateY();
+				ParallelBuilder.build()
+						.add(
+								ConsumerTransition.of(frac -> promptText.setTranslateY(initialTranslateY - (initialTranslateY * frac)), 250)
+										.setInterpolatorFluent(Interpolators.INTERPOLATOR_V1)
+						)
+						.add(
+								KeyFrames.of(250, scale.xProperty(), scaleMultiplier, Interpolators.INTERPOLATOR_V1),
+								KeyFrames.of(250, scale.yProperty(), scaleMultiplier, Interpolators.INTERPOLATOR_V1)
+						)
+						.setOnFinished(end -> System.out.println("Scaled Y: " + promptText.getBoundsInParent().getMinY()))
+						.getAnimation().play();
+				floating = true;
+			}
+		});
+	}
+
+	@Override
+	protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+		return getSkinnable().prefWidth(-1);
+	}
+
+	@Override
+	protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+		return getSkinnable().prefHeight(-1);
+	}
 }

+ 85 - 85
demo/src/test/java/treeview/NumberUtilsTests.java

@@ -7,89 +7,89 @@ import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 public class NumberUtilsTests {
-    private double val;
-    private NumberRange<Double> fromRange;
-    private NumberRange<Double> toRange;
-
-    @Test
-    public void testMap1() {
-        val = 0;
-        fromRange = NumberRange.of(-50.0, 100.0);
-        toRange = NumberRange.of(0.0, 100.0);
-
-        double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
-        assertEquals(33.3, mapped);
-    }
-
-    @Test
-    public void testMap2() {
-        val = -50;
-        fromRange = NumberRange.of(-50.0, 100.0);
-        toRange = NumberRange.of(0.0, 100.0);
-
-        double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
-        assertEquals(0.0, mapped);
-    }
-
-    @Test
-    public void testMap3() {
-        val = 100;
-        fromRange = NumberRange.of(-50.0, 100.0);
-        toRange = NumberRange.of(0.0, 100.0);
-
-        double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
-        assertEquals(100.0, mapped);
-    }
-
-    @Test
-    public void testMap4() {
-        val = -10;
-        fromRange = NumberRange.of(-50.0, 100.0);
-        toRange = NumberRange.of(0.0, 100.0);
-
-        double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
-        assertEquals(26.7, mapped);
-    }
-
-    @Test
-    public void testMap5() {
-        val = 0;
-        fromRange = NumberRange.of(-100.0, 100.0);
-        toRange = NumberRange.of(0.0, 100.0);
-
-        double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
-        assertEquals(50.0, mapped);
-    }
-
-    @Test
-    public void testClamp1() {
-        val = 10;
-
-        double clamped = NumberUtils.clamp(val, 0, 100);
-        assertEquals(10.0, clamped);
-    }
-
-    @Test
-    public void testClamp2() {
-        val = 50;
-
-        double clamped = NumberUtils.clamp(val, 0, 100);
-        assertEquals(50.0, clamped);
-    }
-
-    @Test
-    public void testClamp3() {
-        val = 102;
-
-        double clamped = NumberUtils.clamp(val, 0, 100);
-        assertEquals(100.0, clamped);
-    }
-
-    @Test
-    public void testClamp4() {
-        val = -9;
-
-        double clamped = NumberUtils.clamp(val, 0, 100);
-        assertEquals(0.0, clamped);
-    }
+	private double val;
+	private NumberRange<Double> fromRange;
+	private NumberRange<Double> toRange;
+
+	@Test
+	public void testMap1() {
+		val = 0;
+		fromRange = NumberRange.of(-50.0, 100.0);
+		toRange = NumberRange.of(0.0, 100.0);
+
+		double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
+		assertEquals(33.3, mapped);
+	}
+
+	@Test
+	public void testMap2() {
+		val = -50;
+		fromRange = NumberRange.of(-50.0, 100.0);
+		toRange = NumberRange.of(0.0, 100.0);
+
+		double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
+		assertEquals(0.0, mapped);
+	}
+
+	@Test
+	public void testMap3() {
+		val = 100;
+		fromRange = NumberRange.of(-50.0, 100.0);
+		toRange = NumberRange.of(0.0, 100.0);
+
+		double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
+		assertEquals(100.0, mapped);
+	}
+
+	@Test
+	public void testMap4() {
+		val = -10;
+		fromRange = NumberRange.of(-50.0, 100.0);
+		toRange = NumberRange.of(0.0, 100.0);
+
+		double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
+		assertEquals(26.7, mapped);
+	}
+
+	@Test
+	public void testMap5() {
+		val = 0;
+		fromRange = NumberRange.of(-100.0, 100.0);
+		toRange = NumberRange.of(0.0, 100.0);
+
+		double mapped = NumberUtils.mapOneRangeToAnother(val, fromRange, toRange, 1);
+		assertEquals(50.0, mapped);
+	}
+
+	@Test
+	public void testClamp1() {
+		val = 10;
+
+		double clamped = NumberUtils.clamp(val, 0, 100);
+		assertEquals(10.0, clamped);
+	}
+
+	@Test
+	public void testClamp2() {
+		val = 50;
+
+		double clamped = NumberUtils.clamp(val, 0, 100);
+		assertEquals(50.0, clamped);
+	}
+
+	@Test
+	public void testClamp3() {
+		val = 102;
+
+		double clamped = NumberUtils.clamp(val, 0, 100);
+		assertEquals(100.0, clamped);
+	}
+
+	@Test
+	public void testClamp4() {
+		val = -9;
+
+		double clamped = NumberUtils.clamp(val, 0, 100);
+		assertEquals(0.0, clamped);
+	}
 }

+ 358 - 358
demo/src/test/java/treeview/TreeViewTests.java

@@ -26,362 +26,362 @@ import static org.junit.jupiter.api.Assertions.assertNull;
 
 @ExtendWith(ApplicationExtension.class)
 public class TreeViewTests {
-    private final FxRobot robot = new FxRobot();
-    private final String desktopPath = System.getProperty("user.home") + "/Desktop";
-    private MFXTreeView<String> treeView;
-    private MFXTreeView<String> expandedTreeView;
-    private MFXTreeView<String> complexTreeView;
-
-    @Start
-    public void start(Stage stage) {
-        buildTreeViews();
-        StackPane stackPane = new StackPane(
-                treeView, expandedTreeView, complexTreeView
-        );
-        Scene scene = new Scene(stackPane, 100, 100);
-        stage.setScene(scene);
-        stage.show();
-        stage.toBack();
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testItemsCountRoot() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-
-        long count = root.getItemsCount();
-        assertEquals(12, count);
-
-        AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        count = i1.getItemsCount();
-        assertEquals(4, count);
-        long end = System.nanoTime();
-        System.out.println("TimeCountRoot:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testItemsCountItem() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-        AbstractMFXTreeItem<String> i3 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I3"))
-                .findFirst().orElse(null);
-        long count = i3.getItemsCount();
-        assertEquals(3, count);
-        long end = System.nanoTime();
-        System.out.println("TimeCountItem:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @Test
-    public void testItemCountComplex() throws IOException {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = complexTreeView.getRoot();
-        long expectedCount = fileCount();
-        long count = root.getItemsCount();
-        assertEquals(expectedCount, count);
-        long end = System.nanoTime();
-        System.out.println("TimeCountComplex:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testItemIndex() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-        AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1B"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I2A"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i4a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I4A"))
-                .findFirst().orElse(null);
-
-        assertEquals(0, root.getIndex());
-        assertEquals(1, i1.getIndex());
-        assertEquals(4, i1b.getIndex());
-        assertEquals(6, i2a.getIndex());
-        assertEquals(11, i4a.getIndex());
-        long end = System.nanoTime();
-        System.out.println("TimeIndex:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testItemLevel() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-        AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1B"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I2A"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i11a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I11A"))
-                .findFirst().orElse(null);
-
-        assertEquals(0, root.getLevel());
-        assertEquals(1, i1.getLevel());
-        assertEquals(2, i1b.getLevel());
-        assertEquals(2, i2a.getLevel());
-        assertEquals(3, i11a.getLevel());
-        long end = System.nanoTime();
-        System.out.println("TimeLevel:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @Test
-    public void testTreeViewGet() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-        AbstractMFXTreeItem<String> complexRoot = complexTreeView.getRoot();
-
-        TreeItemStream.stream(root).forEach(item -> assertEquals(treeView, item.getTreeView()));
-        TreeItemStream.stream(complexRoot).forEach(item -> assertEquals(complexTreeView, item.getTreeView()));
-        long end = System.nanoTime();
-        System.out.println("TimeTreeViewGet:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testNextSiblings() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-        AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1B"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I2A"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i3a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I3A"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i4 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I4"))
-                .findFirst().orElse(null);
-
-        assertNull(root.getNextSibling());
-        assertEquals("I2", i1.getNextSibling().getData());
-        assertNull(i1b.getNextSibling());
-        assertNull(i2a.getNextSibling());
-        assertEquals("I3B", i3a.getNextSibling().getData());
-        assertNull(i4.getNextSibling());
-        long end = System.nanoTime();
-        System.out.println("TimeNextSiblings:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testPreviousSiblings() {
-        long start = System.nanoTime();
-        AbstractMFXTreeItem<String> root = treeView.getRoot();
-        AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1B"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I2A"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i3a = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I3A"))
-                .findFirst().orElse(null);
-        AbstractMFXTreeItem<String> i4 = TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I4"))
-                .findFirst().orElse(null);
-
-        assertNull(root.getPreviousSibling());
-        assertNull(i1.getPreviousSibling());
-        assertEquals("I1A", i1b.getPreviousSibling().getData());
-        assertNull(i2a.getPreviousSibling());
-        assertNull(i3a.getPreviousSibling());
-        assertEquals("I3", i4.getPreviousSibling().getData());
-        long end = System.nanoTime();
-        System.out.println("TimePreviousSiblings:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testSelected() {
-        long start = System.nanoTime();
-        MFXTreeItem<String> root = (MFXTreeItem<String>) treeView.getRoot();
-        treeView.getSelectionModel().setAllowsMultipleSelection(false);
-        MFXTreeItem<String> i1 = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        MFXTreeItem<String> i1b = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1B"))
-                .findFirst().orElse(null);
-        MFXTreeItem<String> i2a = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I2A"))
-                .findFirst().orElse(null);
-        MFXTreeItem<String> i3 = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I3"))
-                .findFirst().orElse(null);
-
-        root.setSelected(true);
-        i1.setSelected(true);
-        i1b.setSelected(true);
-        i2a.setSelected(true);
-        i3.setSelected(true);
-
-        assertEquals(1, treeView.getSelectionModel().getSelectedItems().size());
-        assertEquals(i3, treeView.getSelectionModel().getSelectedItem());
-        long end = System.nanoTime();
-        System.out.println("TimeSelected:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testSelectedMultiple() {
-        long start = System.nanoTime();
-        MFXTreeItem<String> root = (MFXTreeItem<String>) treeView.getRoot();
-        MFXTreeItem<String> i1 = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-        MFXTreeItem<String> i1b = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1B"))
-                .findFirst().orElse(null);
-        MFXTreeItem<String> i2a = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I2A"))
-                .findFirst().orElse(null);
-        MFXTreeItem<String> i3 = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I3"))
-                .findFirst().orElse(null);
-
-        root.setSelected(true);
-        i1.setSelected(true);
-        i1b.setSelected(true);
-        i2a.setSelected(true);
-        i3.setSelected(true);
-
-        assertEquals(5, treeView.getSelectionModel().getSelectedItems().size());
-        long end = System.nanoTime();
-        System.out.println("TimeSelectedMultiple:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    @Test
-    public void testSetItems() {
-        long start = System.nanoTime();
-        MFXTreeItem<String> root = (MFXTreeItem<String>) treeView.getRoot();
-        MFXTreeItem<String> i1 = (MFXTreeItem<String>) TreeItemStream.stream(root)
-                .filter(i -> i.getData().equals("I1"))
-                .findFirst().orElse(null);
-
-        robot.interact(() -> i1.setItems(FXCollections.observableArrayList()));
-
-        assertEquals(9, root.getItemsCount());
-        long end = System.nanoTime();
-        System.out.println("TimeSelectedMultiple:" + ((double) (end - start) / 1000000) + "ms");
-    }
-
-    //================================================================================
-    // OTHER METHODS
-    //================================================================================
-    private void createTree(File file, MFXTreeItem<String> parent) {
-        if (file.isDirectory()) {
-            MFXTreeItem<String> treeItem = new MFXTreeItem<>(file.getName());
-            parent.getItems().add(treeItem);
-            File[] fileList = file.listFiles();
-            if (fileList != null) {
-                for (File f : fileList) {
-                    createTree(f, treeItem);
-                }
-            }
-        } else {
-            parent.getItems().add(new MFXTreeItem<>(file.getName()));
-        }
-    }
-
-    private long fileCount() throws IOException {
-        return Files.walk(Paths.get(desktopPath).toAbsolutePath())
-                .parallel()
-                .count();
-    }
-
-    private void buildTreeViews() {
-        MFXTreeItem<String> root = new MFXTreeItem<>("ROOT");
-        MFXTreeItem<String> i1 = new MFXTreeItem<>("I1");
-        MFXTreeItem<String> i1a = new MFXTreeItem<>("I1A");
-        i1a.getItems().add(new MFXTreeItem<>("I11A"));
-
-        MFXTreeItem<String> i1b = new MFXTreeItem<>("I1B");
-        i1.getItems().addAll(List.of(i1a, i1b));
-
-        MFXTreeItem<String> i2 = new MFXTreeItem<>("I2");
-        MFXTreeItem<String> i2a = new MFXTreeItem<>("I2A");
-        i2.getItems().add(i2a);
-
-        MFXTreeItem<String> i3 = new MFXTreeItem<>("I3");
-        MFXTreeItem<String> i3a = new MFXTreeItem<>("I3A");
-        MFXTreeItem<String> i3b = new MFXTreeItem<>("I3B");
-        i3.getItems().addAll(List.of(i3a, i3b));
-
-        MFXTreeItem<String> i4 = new MFXTreeItem<>("I4");
-        MFXTreeItem<String> i4a = new MFXTreeItem<>("I4A");
-        i4.getItems().add(i4a);
-
-        root.getItems().addAll(List.of(i1, i2, i3, i4));
-        treeView = new MFXTreeView<>(root);
-
-        buildExpandedTree();
-
-        Path dir = Paths.get(desktopPath).toAbsolutePath();
-        MFXTreeItem<String> complexRoot = new MFXTreeItem<>(desktopPath);
-        File[] fileList = dir.toFile().listFiles();
-        if (fileList != null) {
-            for (File file : fileList) {
-                createTree(file, complexRoot);
-            }
-        }
-        complexTreeView = new MFXTreeView<>(complexRoot);
-    }
-
-    private void buildExpandedTree() {
-        MFXTreeItem<String> root = new MFXTreeItem<>("ROOT");
-        MFXTreeItem<String> i1 = new MFXTreeItem<>("I1");
-        MFXTreeItem<String> i1a = new MFXTreeItem<>("I1A");
-        i1a.getItems().add(new MFXTreeItem<>("I11A"));
-
-        MFXTreeItem<String> i1b = new MFXTreeItem<>("I1B");
-        i1.getItems().addAll(List.of(i1a, i1b));
-
-        MFXTreeItem<String> i2 = new MFXTreeItem<>("I2");
-        MFXTreeItem<String> i2a = new MFXTreeItem<>("I2A");
-        i2.getItems().add(i2a);
-
-        MFXTreeItem<String> i3 = new MFXTreeItem<>("I3");
-        MFXTreeItem<String> i3a = new MFXTreeItem<>("I3A");
-        MFXTreeItem<String> i3b = new MFXTreeItem<>("I3B");
-        i3.getItems().addAll(List.of(i3a, i3b));
-
-        MFXTreeItem<String> i4 = new MFXTreeItem<>("I4");
-        MFXTreeItem<String> i4a = new MFXTreeItem<>("I4A");
-        i4.getItems().add(i4a);
-
-        root.getItems().addAll(List.of(i1, i2, i3, i4));
-        expandedTreeView = new MFXTreeView<>(root);
-
-        root.setStartExpanded(true);
-        i1.setStartExpanded(true);
-        i1b.setStartExpanded(true);
-        i2a.setStartExpanded(true);
-        i3.setStartExpanded(true);
-    }
+	private final FxRobot robot = new FxRobot();
+	private final String desktopPath = System.getProperty("user.home") + "/Desktop";
+	private MFXTreeView<String> treeView;
+	private MFXTreeView<String> expandedTreeView;
+	private MFXTreeView<String> complexTreeView;
+
+	@Start
+	public void start(Stage stage) {
+		buildTreeViews();
+		StackPane stackPane = new StackPane(
+				treeView, expandedTreeView, complexTreeView
+		);
+		Scene scene = new Scene(stackPane, 100, 100);
+		stage.setScene(scene);
+		stage.show();
+		stage.toBack();
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testItemsCountRoot() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+
+		long count = root.getItemsCount();
+		assertEquals(12, count);
+
+		AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		count = i1.getItemsCount();
+		assertEquals(4, count);
+		long end = System.nanoTime();
+		System.out.println("TimeCountRoot:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testItemsCountItem() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+		AbstractMFXTreeItem<String> i3 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I3"))
+				.findFirst().orElse(null);
+		long count = i3.getItemsCount();
+		assertEquals(3, count);
+		long end = System.nanoTime();
+		System.out.println("TimeCountItem:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@Test
+	public void testItemCountComplex() throws IOException {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = complexTreeView.getRoot();
+		long expectedCount = fileCount();
+		long count = root.getItemsCount();
+		assertEquals(expectedCount, count);
+		long end = System.nanoTime();
+		System.out.println("TimeCountComplex:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testItemIndex() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+		AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1B"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I2A"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i4a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I4A"))
+				.findFirst().orElse(null);
+
+		assertEquals(0, root.getIndex());
+		assertEquals(1, i1.getIndex());
+		assertEquals(4, i1b.getIndex());
+		assertEquals(6, i2a.getIndex());
+		assertEquals(11, i4a.getIndex());
+		long end = System.nanoTime();
+		System.out.println("TimeIndex:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testItemLevel() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+		AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1B"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I2A"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i11a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I11A"))
+				.findFirst().orElse(null);
+
+		assertEquals(0, root.getLevel());
+		assertEquals(1, i1.getLevel());
+		assertEquals(2, i1b.getLevel());
+		assertEquals(2, i2a.getLevel());
+		assertEquals(3, i11a.getLevel());
+		long end = System.nanoTime();
+		System.out.println("TimeLevel:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@Test
+	public void testTreeViewGet() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+		AbstractMFXTreeItem<String> complexRoot = complexTreeView.getRoot();
+
+		TreeItemStream.stream(root).forEach(item -> assertEquals(treeView, item.getTreeView()));
+		TreeItemStream.stream(complexRoot).forEach(item -> assertEquals(complexTreeView, item.getTreeView()));
+		long end = System.nanoTime();
+		System.out.println("TimeTreeViewGet:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testNextSiblings() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+		AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1B"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I2A"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i3a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I3A"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i4 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I4"))
+				.findFirst().orElse(null);
+
+		assertNull(root.getNextSibling());
+		assertEquals("I2", i1.getNextSibling().getData());
+		assertNull(i1b.getNextSibling());
+		assertNull(i2a.getNextSibling());
+		assertEquals("I3B", i3a.getNextSibling().getData());
+		assertNull(i4.getNextSibling());
+		long end = System.nanoTime();
+		System.out.println("TimeNextSiblings:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testPreviousSiblings() {
+		long start = System.nanoTime();
+		AbstractMFXTreeItem<String> root = treeView.getRoot();
+		AbstractMFXTreeItem<String> i1 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i1b = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1B"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i2a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I2A"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i3a = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I3A"))
+				.findFirst().orElse(null);
+		AbstractMFXTreeItem<String> i4 = TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I4"))
+				.findFirst().orElse(null);
+
+		assertNull(root.getPreviousSibling());
+		assertNull(i1.getPreviousSibling());
+		assertEquals("I1A", i1b.getPreviousSibling().getData());
+		assertNull(i2a.getPreviousSibling());
+		assertNull(i3a.getPreviousSibling());
+		assertEquals("I3", i4.getPreviousSibling().getData());
+		long end = System.nanoTime();
+		System.out.println("TimePreviousSiblings:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testSelected() {
+		long start = System.nanoTime();
+		MFXTreeItem<String> root = (MFXTreeItem<String>) treeView.getRoot();
+		treeView.getSelectionModel().setAllowsMultipleSelection(false);
+		MFXTreeItem<String> i1 = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		MFXTreeItem<String> i1b = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1B"))
+				.findFirst().orElse(null);
+		MFXTreeItem<String> i2a = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I2A"))
+				.findFirst().orElse(null);
+		MFXTreeItem<String> i3 = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I3"))
+				.findFirst().orElse(null);
+
+		root.setSelected(true);
+		i1.setSelected(true);
+		i1b.setSelected(true);
+		i2a.setSelected(true);
+		i3.setSelected(true);
+
+		assertEquals(1, treeView.getSelectionModel().getSelectedItems().size());
+		assertEquals(i3, treeView.getSelectionModel().getSelectedItem());
+		long end = System.nanoTime();
+		System.out.println("TimeSelected:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testSelectedMultiple() {
+		long start = System.nanoTime();
+		MFXTreeItem<String> root = (MFXTreeItem<String>) treeView.getRoot();
+		MFXTreeItem<String> i1 = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+		MFXTreeItem<String> i1b = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1B"))
+				.findFirst().orElse(null);
+		MFXTreeItem<String> i2a = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I2A"))
+				.findFirst().orElse(null);
+		MFXTreeItem<String> i3 = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I3"))
+				.findFirst().orElse(null);
+
+		root.setSelected(true);
+		i1.setSelected(true);
+		i1b.setSelected(true);
+		i2a.setSelected(true);
+		i3.setSelected(true);
+
+		assertEquals(5, treeView.getSelectionModel().getSelectedItems().size());
+		long end = System.nanoTime();
+		System.out.println("TimeSelectedMultiple:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	@SuppressWarnings("ConstantConditions")
+	@Test
+	public void testSetItems() {
+		long start = System.nanoTime();
+		MFXTreeItem<String> root = (MFXTreeItem<String>) treeView.getRoot();
+		MFXTreeItem<String> i1 = (MFXTreeItem<String>) TreeItemStream.stream(root)
+				.filter(i -> i.getData().equals("I1"))
+				.findFirst().orElse(null);
+
+		robot.interact(() -> i1.setItems(FXCollections.observableArrayList()));
+
+		assertEquals(9, root.getItemsCount());
+		long end = System.nanoTime();
+		System.out.println("TimeSelectedMultiple:" + ((double) (end - start) / 1000000) + "ms");
+	}
+
+	//================================================================================
+	// OTHER METHODS
+	//================================================================================
+	private void createTree(File file, MFXTreeItem<String> parent) {
+		if (file.isDirectory()) {
+			MFXTreeItem<String> treeItem = new MFXTreeItem<>(file.getName());
+			parent.getItems().add(treeItem);
+			File[] fileList = file.listFiles();
+			if (fileList != null) {
+				for (File f : fileList) {
+					createTree(f, treeItem);
+				}
+			}
+		} else {
+			parent.getItems().add(new MFXTreeItem<>(file.getName()));
+		}
+	}
+
+	private long fileCount() throws IOException {
+		return Files.walk(Paths.get(desktopPath).toAbsolutePath())
+				.parallel()
+				.count();
+	}
+
+	private void buildTreeViews() {
+		MFXTreeItem<String> root = new MFXTreeItem<>("ROOT");
+		MFXTreeItem<String> i1 = new MFXTreeItem<>("I1");
+		MFXTreeItem<String> i1a = new MFXTreeItem<>("I1A");
+		i1a.getItems().add(new MFXTreeItem<>("I11A"));
+
+		MFXTreeItem<String> i1b = new MFXTreeItem<>("I1B");
+		i1.getItems().addAll(List.of(i1a, i1b));
+
+		MFXTreeItem<String> i2 = new MFXTreeItem<>("I2");
+		MFXTreeItem<String> i2a = new MFXTreeItem<>("I2A");
+		i2.getItems().add(i2a);
+
+		MFXTreeItem<String> i3 = new MFXTreeItem<>("I3");
+		MFXTreeItem<String> i3a = new MFXTreeItem<>("I3A");
+		MFXTreeItem<String> i3b = new MFXTreeItem<>("I3B");
+		i3.getItems().addAll(List.of(i3a, i3b));
+
+		MFXTreeItem<String> i4 = new MFXTreeItem<>("I4");
+		MFXTreeItem<String> i4a = new MFXTreeItem<>("I4A");
+		i4.getItems().add(i4a);
+
+		root.getItems().addAll(List.of(i1, i2, i3, i4));
+		treeView = new MFXTreeView<>(root);
+
+		buildExpandedTree();
+
+		Path dir = Paths.get(desktopPath).toAbsolutePath();
+		MFXTreeItem<String> complexRoot = new MFXTreeItem<>(desktopPath);
+		File[] fileList = dir.toFile().listFiles();
+		if (fileList != null) {
+			for (File file : fileList) {
+				createTree(file, complexRoot);
+			}
+		}
+		complexTreeView = new MFXTreeView<>(complexRoot);
+	}
+
+	private void buildExpandedTree() {
+		MFXTreeItem<String> root = new MFXTreeItem<>("ROOT");
+		MFXTreeItem<String> i1 = new MFXTreeItem<>("I1");
+		MFXTreeItem<String> i1a = new MFXTreeItem<>("I1A");
+		i1a.getItems().add(new MFXTreeItem<>("I11A"));
+
+		MFXTreeItem<String> i1b = new MFXTreeItem<>("I1B");
+		i1.getItems().addAll(List.of(i1a, i1b));
+
+		MFXTreeItem<String> i2 = new MFXTreeItem<>("I2");
+		MFXTreeItem<String> i2a = new MFXTreeItem<>("I2A");
+		i2.getItems().add(i2a);
+
+		MFXTreeItem<String> i3 = new MFXTreeItem<>("I3");
+		MFXTreeItem<String> i3a = new MFXTreeItem<>("I3A");
+		MFXTreeItem<String> i3b = new MFXTreeItem<>("I3B");
+		i3.getItems().addAll(List.of(i3a, i3b));
+
+		MFXTreeItem<String> i4 = new MFXTreeItem<>("I4");
+		MFXTreeItem<String> i4a = new MFXTreeItem<>("I4A");
+		i4.getItems().add(i4a);
+
+		root.getItems().addAll(List.of(i1, i2, i3, i4));
+		expandedTreeView = new MFXTreeView<>(root);
+
+		root.setStartExpanded(true);
+		i1.setStartExpanded(true);
+		i1b.setStartExpanded(true);
+		i2a.setStartExpanded(true);
+		i3.setStartExpanded(true);
+	}
 }

+ 2 - 2
materialfx/build.gradle

@@ -78,9 +78,9 @@ task copyJar(type: Copy) {
     from jar
     if (Os.isFamily(Os.FAMILY_WINDOWS)) {
         into System.getenv("APPDATA") + '/Scene Builder/Library'
-    } else if(Os.isFamily(Os.FAMILY_MAC)) {
+    } else if (Os.isFamily(Os.FAMILY_MAC)) {
         into System.getProperty("user.home") + '/Library/Application Support' + '/Scene Builder/Library'
-    } else if(Os.isFamily(Os.FAMILY_UNIX)) {
+    } else if (Os.isFamily(Os.FAMILY_UNIX)) {
         into System.getProperty("user.home") + '/.scenebuilder/Library'
     }
 }

+ 10 - 10
materialfx/src/main/java/io/github/palexdev/materialfx/MFXResourcesLoader.java

@@ -27,17 +27,17 @@ import java.net.URL;
  */
 public class MFXResourcesLoader {
 
-    private MFXResourcesLoader() {}
+	private MFXResourcesLoader() {}
 
-    public static URL loadURL(String path) {
-        return MFXResourcesLoader.class.getResource(path);
-    }
+	public static URL loadURL(String path) {
+		return MFXResourcesLoader.class.getResource(path);
+	}
 
-    public static String load(String path) {
-        return loadURL(path).toString();
-    }
+	public static String load(String path) {
+		return loadURL(path).toString();
+	}
 
-    public static InputStream loadStream(String name) {
-        return MFXResourcesLoader.class.getResourceAsStream(name);
-    }
+	public static InputStream loadStream(String name) {
+		return MFXResourcesLoader.class.getResourceAsStream(name);
+	}
 }

+ 41 - 41
materialfx/src/main/java/io/github/palexdev/materialfx/beans/AnimationsData.java

@@ -28,52 +28,52 @@ import javafx.util.Duration;
  * an action to perform when the animation ends.
  */
 public class AnimationsData {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final Node node;
-    private final Duration duration;
-    private final EventHandler<ActionEvent> onFinished;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final Node node;
+	private final Duration duration;
+	private final EventHandler<ActionEvent> onFinished;
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public AnimationsData(Node node, Duration duration, EventHandler<ActionEvent> onFinished) {
-        this.node = node;
-        this.duration = duration;
-        this.onFinished = onFinished;
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public AnimationsData(Node node, Duration duration, EventHandler<ActionEvent> onFinished) {
+		this.node = node;
+		this.duration = duration;
+		this.onFinished = onFinished;
+	}
 
-    //================================================================================
-    // Methods
-    //================================================================================
-    public Node node() {
-        return node;
-    }
+	//================================================================================
+	// Methods
+	//================================================================================
+	public Node node() {
+		return node;
+	}
 
-    public Duration duration() {
-        return duration;
-    }
+	public Duration duration() {
+		return duration;
+	}
 
-    public EventHandler<ActionEvent> onFinished() {
-        return onFinished;
-    }
+	public EventHandler<ActionEvent> onFinished() {
+		return onFinished;
+	}
 
-    //================================================================================
-    // Static Methods
-    //================================================================================
+	//================================================================================
+	// Static Methods
+	//================================================================================
 
-    /**
-     * Builds a new AnimationsData object with the given node and duration, the action is set to null.
-     */
-    public static AnimationsData of(Node node, Duration duration) {
-        return of(node, duration, null);
-    }
+	/**
+	 * Builds a new AnimationsData object with the given node and duration, the action is set to null.
+	 */
+	public static AnimationsData of(Node node, Duration duration) {
+		return of(node, duration, null);
+	}
 
-    /**
-     * Builds a new AnimationsData object with the given node and duration and action.
-     */
-    public static AnimationsData of(Node node, Duration duration, EventHandler<ActionEvent> onFinished) {
-        return new AnimationsData(node, duration, onFinished);
-    }
+	/**
+	 * Builds a new AnimationsData object with the given node and duration and action.
+	 */
+	public static AnimationsData of(Node node, Duration duration, EventHandler<ActionEvent> onFinished) {
+		return new AnimationsData(node, duration, onFinished);
+	}
 }

+ 25 - 25
materialfx/src/main/java/io/github/palexdev/materialfx/beans/BiPredicateBean.java

@@ -10,33 +10,33 @@ import java.util.function.BiPredicate;
  * @param <U> the type of the second argument the predicate
  */
 public class BiPredicateBean<T, U> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final String name;
-    private final BiPredicate<T, U> predicate;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final String name;
+	private final BiPredicate<T, U> predicate;
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public BiPredicateBean(String name, BiPredicate<T, U> predicate) {
-        this.name = name;
-        this.predicate = predicate;
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public BiPredicateBean(String name, BiPredicate<T, U> predicate) {
+		this.name = name;
+		this.predicate = predicate;
+	}
 
-    //================================================================================
-    // Getters
-    //================================================================================
-    public String name() {
-        return name;
-    }
+	//================================================================================
+	// Getters
+	//================================================================================
+	public String name() {
+		return name;
+	}
 
-    public BiPredicate<T, U> predicate() {
-        return predicate;
-    }
+	public BiPredicate<T, U> predicate() {
+		return predicate;
+	}
 
-    @Override
-    public String toString() {
-        return name;
-    }
+	@Override
+	public String toString() {
+		return name;
+	}
 }

+ 69 - 69
materialfx/src/main/java/io/github/palexdev/materialfx/beans/CustomBounds.java

@@ -15,84 +15,84 @@ import javafx.geometry.Bounds;
  * notification center. Like I said tough, cases like that are quite rare.
  */
 public class CustomBounds {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final double minX;
-    private final double minY;
-    private final double minZ;
-    private final double maxX;
-    private final double maxY;
-    private final double maxZ;
-    private final double width;
-    private final double height;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final double minX;
+	private final double minY;
+	private final double minZ;
+	private final double maxX;
+	private final double maxY;
+	private final double maxZ;
+	private final double width;
+	private final double height;
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public CustomBounds(double minX, double minY, double maxX, double maxY, double width, double height) {
-        this(minX, minY, 0, maxX, maxY, 0, width, height);
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public CustomBounds(double minX, double minY, double maxX, double maxY, double width, double height) {
+		this(minX, minY, 0, maxX, maxY, 0, width, height);
+	}
 
-    public CustomBounds(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, double width, double height) {
-        this.minX = minX;
-        this.minY = minY;
-        this.minZ = minZ;
-        this.maxX = maxX;
-        this.maxY = maxY;
-        this.maxZ = maxZ;
-        this.width = width;
-        this.height = height;
-    }
+	public CustomBounds(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, double width, double height) {
+		this.minX = minX;
+		this.minY = minY;
+		this.minZ = minZ;
+		this.maxX = maxX;
+		this.maxY = maxY;
+		this.maxZ = maxZ;
+		this.width = width;
+		this.height = height;
+	}
 
-    //================================================================================
-    // Static Methods
-    //================================================================================
-    public static CustomBounds from(Bounds bounds) {
-        return new CustomBounds(
-                bounds.getMinX(),
-                bounds.getMinY(),
-                bounds.getMinZ(),
-                bounds.getMaxX(),
-                bounds.getMaxY(),
-                bounds.getMaxY(),
-                bounds.getWidth(),
-                bounds.getHeight()
-        );
-    }
+	//================================================================================
+	// Static Methods
+	//================================================================================
+	public static CustomBounds from(Bounds bounds) {
+		return new CustomBounds(
+				bounds.getMinX(),
+				bounds.getMinY(),
+				bounds.getMinZ(),
+				bounds.getMaxX(),
+				bounds.getMaxY(),
+				bounds.getMaxY(),
+				bounds.getWidth(),
+				bounds.getHeight()
+		);
+	}
 
-    //================================================================================
-    // Getters/Setters
-    //================================================================================
-    public double getMinX() {
-        return minX;
-    }
+	//================================================================================
+	// Getters/Setters
+	//================================================================================
+	public double getMinX() {
+		return minX;
+	}
 
-    public double getMinY() {
-        return minY;
-    }
+	public double getMinY() {
+		return minY;
+	}
 
-    public double getMinZ() {
-        return minZ;
-    }
+	public double getMinZ() {
+		return minZ;
+	}
 
-    public double getMaxX() {
-        return maxX;
-    }
+	public double getMaxX() {
+		return maxX;
+	}
 
-    public double getMaxY() {
-        return maxY;
-    }
+	public double getMaxY() {
+		return maxY;
+	}
 
-    public double getMaxZ() {
-        return maxZ;
-    }
+	public double getMaxZ() {
+		return maxZ;
+	}
 
-    public double getWidth() {
-        return width;
-    }
+	public double getWidth() {
+		return width;
+	}
 
-    public double getHeight() {
-        return height;
-    }
+	public double getHeight() {
+		return height;
+	}
 }

+ 70 - 70
materialfx/src/main/java/io/github/palexdev/materialfx/beans/FilterBean.java

@@ -20,85 +20,85 @@ import java.util.function.Predicate;
  * @param <U> the type of objects on which the {@link BiPredicate} operates
  */
 public class FilterBean<T, U> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final String query;
-    private final AbstractFilter<T, U> filter;
-    private final BiPredicateBean<U, U> predicateBean;
-    private ChainMode mode;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final String query;
+	private final AbstractFilter<T, U> filter;
+	private final BiPredicateBean<U, U> predicateBean;
+	private ChainMode mode;
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public FilterBean(String query, AbstractFilter<T, U> filter, BiPredicateBean<U, U> predicateBean) {
-        this(query, filter, predicateBean, ChainMode.OR);
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public FilterBean(String query, AbstractFilter<T, U> filter, BiPredicateBean<U, U> predicateBean) {
+		this(query, filter, predicateBean, ChainMode.OR);
+	}
 
-    public FilterBean(String query, AbstractFilter<T, U> filter, BiPredicateBean<U, U> predicateBean, ChainMode mode) {
-        this.query = query;
-        this.filter = filter;
-        this.predicateBean = predicateBean;
-        this.mode = mode;
-    }
+	public FilterBean(String query, AbstractFilter<T, U> filter, BiPredicateBean<U, U> predicateBean, ChainMode mode) {
+		this.query = query;
+		this.filter = filter;
+		this.predicateBean = predicateBean;
+		this.mode = mode;
+	}
 
-    //================================================================================
-    // Methods
-    //================================================================================
+	//================================================================================
+	// Methods
+	//================================================================================
 
-    /**
-     * Calls {@link AbstractFilter#predicateFor(String)} with the query specified by this bean.
-     */
-    public Predicate<T> predicate() {
-        return filter.predicateFor(query);
-    }
+	/**
+	 * Calls {@link AbstractFilter#predicateFor(String)} with the query specified by this bean.
+	 */
+	public Predicate<T> predicate() {
+		return filter.predicateFor(query);
+	}
 
-    /**
-     * @return the query, see {@link AbstractFilter} documentation for more info about the query
-     */
-    public String getQuery() {
-        return query;
-    }
+	/**
+	 * @return the query, see {@link AbstractFilter} documentation for more info about the query
+	 */
+	public String getQuery() {
+		return query;
+	}
 
-    /**
-     * @return the {@link AbstractFilter} specified by this bean
-     */
-    public AbstractFilter<T, U> getFilter() {
-        return filter;
-    }
+	/**
+	 * @return the {@link AbstractFilter} specified by this bean
+	 */
+	public AbstractFilter<T, U> getFilter() {
+		return filter;
+	}
 
-    /**
-     * Delegate for {@link AbstractFilter#name()}.
-     */
-    public String getFilterName() {
-        return filter.name();
-    }
+	/**
+	 * Delegate for {@link AbstractFilter#name()}.
+	 */
+	public String getFilterName() {
+		return filter.name();
+	}
 
-    /**
-     * @return the {@link BiPredicateBean} specified by this bean
-     */
-    public BiPredicateBean<U, U> getPredicateBean() {
-        return predicateBean;
-    }
+	/**
+	 * @return the {@link BiPredicateBean} specified by this bean
+	 */
+	public BiPredicateBean<U, U> getPredicateBean() {
+		return predicateBean;
+	}
 
-    /**
-     * Delegate for {@link BiPredicateBean#name()}.
-     */
-    public String getPredicateName() {
-        return predicateBean.name();
-    }
+	/**
+	 * Delegate for {@link BiPredicateBean#name()}.
+	 */
+	public String getPredicateName() {
+		return predicateBean.name();
+	}
 
-    /**
-     * @return the {@link ChainMode} enumeration that specifies how this filter should be chained with other filters.
-     */
-    public ChainMode getMode() {
-        return mode;
-    }
+	/**
+	 * @return the {@link ChainMode} enumeration that specifies how this filter should be chained with other filters.
+	 */
+	public ChainMode getMode() {
+		return mode;
+	}
 
-    /**
-     * Sets the chain mode to the specified one.
-     */
-    public void setMode(ChainMode mode) {
-        this.mode = mode;
-    }
+	/**
+	 * Sets the chain mode to the specified one.
+	 */
+	public void setMode(ChainMode mode) {
+		this.mode = mode;
+	}
 }

+ 10 - 10
materialfx/src/main/java/io/github/palexdev/materialfx/beans/MFXSnapshotWrapper.java

@@ -34,16 +34,16 @@ import javafx.scene.paint.Color;
  * graphic, however it should be acceptable and I believe this is still better than having no graphic at all.
  */
 public class MFXSnapshotWrapper {
-    private final WritableImage snapshot;
+	private final WritableImage snapshot;
 
-    public MFXSnapshotWrapper(Node node) {
-        SnapshotParameters snapshotParameters = new SnapshotParameters();
-        snapshotParameters.setFill(Color.TRANSPARENT);
-        snapshotParameters.setDepthBuffer(true);
-        snapshot = node.snapshot(snapshotParameters, null);
-    }
+	public MFXSnapshotWrapper(Node node) {
+		SnapshotParameters snapshotParameters = new SnapshotParameters();
+		snapshotParameters.setFill(Color.TRANSPARENT);
+		snapshotParameters.setDepthBuffer(true);
+		snapshot = node.snapshot(snapshotParameters, null);
+	}
 
-    public Node getGraphic() {
-        return new ImageView(snapshot);
-    }
+	public Node getGraphic() {
+		return new ImageView(snapshot);
+	}
 }

+ 157 - 157
materialfx/src/main/java/io/github/palexdev/materialfx/beans/NumberRange.java

@@ -27,161 +27,161 @@ import java.util.stream.IntStream;
  * @param <T> The type of Number to represent
  */
 public class NumberRange<T extends Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final T min;
-    private final T max;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public NumberRange(T min, T max) {
-        this.min = min;
-        this.max = max;
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * @return the lower bound
-     */
-    public T getMin() {
-        return min;
-    }
-
-    /**
-     * @return the upper bound
-     */
-    public T getMax() {
-        return max;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        NumberRange<?> that = (NumberRange<?>) o;
-        return Objects.equals(min, that.min) && Objects.equals(max, that.max);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(min, max);
-    }
-
-    @Override
-    public String toString() {
-        return "Min[" + min + "], Max[" + max + "]";
-    }
-    //================================================================================
-    // Static Methods
-    //================================================================================
-
-    /**
-     * Returns a new instance of NumberRange with the given min and max bounds.
-     */
-    public static <T extends Number> NumberRange<T> of(T min, T max) {
-        return new NumberRange<>(min, max);
-    }
-
-    /**
-     * Returns a new instance of NumberRange with the given val as both min and max bounds.
-     */
-    public static <T extends Number> NumberRange<T> of(T val) {
-        return new NumberRange<>(val, val);
-    }
-
-    /**
-     * Checks if the given value is contained in the given range (bounds are included).
-     */
-    public static boolean inRangeOf(double val, NumberRange<Double> range) {
-        return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
-    }
-
-    /**
-     * Checks if the given value is contained in the given range (bounds are included).
-     */
-    public static boolean inRangeOf(float val, NumberRange<Float> range) {
-        return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
-    }
-
-    /**
-     * Checks if the given value is contained in the given range (bounds are included).
-     */
-    public static boolean inRangeOf(int val, NumberRange<Integer> range) {
-        return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
-    }
-
-    /**
-     * Checks if the given value is contained in the given range (bounds are included).
-     */
-    public static boolean inRangeOf(long val, NumberRange<Long> range) {
-        return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
-    }
-
-    /**
-     * Checks if the given value is contained in any of the given ranges (bounds are included).
-     */
-    public static boolean inRangeOf(double val, List<NumberRange<Double>> ranges) {
-        return ranges.stream().anyMatch(range -> inRangeOf(val, range));
-    }
-
-    /**
-     * Checks if the given value is contained in any of the given ranges (bounds are included).
-     */
-    public static boolean inRangeOf(float val, List<NumberRange<Float>> ranges) {
-        return ranges.stream().anyMatch(range -> inRangeOf(val, range));
-    }
-
-    /**
-     * Checks if the given value is contained in any of the given ranges (bounds are included).
-     */
-    public static boolean inRangeOf(int val, List<NumberRange<Integer>> ranges) {
-        return ranges.stream().anyMatch(range -> inRangeOf(val, range));
-    }
-
-    /**
-     * Checks if the given value is contained in any of the given ranges (bounds are included).
-     */
-    public static boolean inRangeOf(long val, List<NumberRange<Long>> ranges) {
-        return ranges.stream().anyMatch(range -> inRangeOf(val, range));
-    }
-
-    /**
-     * Expands a range of integers to a List of integers.
-     */
-    public static List<Integer> expandRange(NumberRange<Integer> range) {
-        return IntStream.rangeClosed(range.getMin(), range.getMax()).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
-    }
-
-    /**
-     * Expands a range of integers to a List of integers.
-     */
-    public static List<Integer> expandRange(int min, int max) {
-        return IntStream.rangeClosed(min, max).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
-    }
-
-    /**
-     * Expands a range of integers to a Set of integers.
-     */
-    public static Set<Integer> expandRangeToSet(NumberRange<Integer> range) {
-        return IntStream.rangeClosed(range.getMin(), range.getMax()).collect(HashSet::new, HashSet::add, HashSet::addAll);
-    }
-
-    /**
-     * Expands a range of integers to a Set of integers.
-     */
-    public static Set<Integer> expandRangeToSet(int min, int max) {
-        return IntStream.rangeClosed(min, max).collect(HashSet::new, HashSet::add, HashSet::addAll);
-    }
-
-    /**
-     * Expands a range of integers to an array of integers.
-     */
-    public static Integer[] expandRangeToArray(int min, int max) {
-        return IntStream.rangeClosed(min, max).boxed().toArray(Integer[]::new);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final T min;
+	private final T max;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public NumberRange(T min, T max) {
+		this.min = min;
+		this.max = max;
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * @return the lower bound
+	 */
+	public T getMin() {
+		return min;
+	}
+
+	/**
+	 * @return the upper bound
+	 */
+	public T getMax() {
+		return max;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+		NumberRange<?> that = (NumberRange<?>) o;
+		return Objects.equals(min, that.min) && Objects.equals(max, that.max);
+	}
+
+	@Override
+	public int hashCode() {
+		return Objects.hash(min, max);
+	}
+
+	@Override
+	public String toString() {
+		return "Min[" + min + "], Max[" + max + "]";
+	}
+	//================================================================================
+	// Static Methods
+	//================================================================================
+
+	/**
+	 * Returns a new instance of NumberRange with the given min and max bounds.
+	 */
+	public static <T extends Number> NumberRange<T> of(T min, T max) {
+		return new NumberRange<>(min, max);
+	}
+
+	/**
+	 * Returns a new instance of NumberRange with the given val as both min and max bounds.
+	 */
+	public static <T extends Number> NumberRange<T> of(T val) {
+		return new NumberRange<>(val, val);
+	}
+
+	/**
+	 * Checks if the given value is contained in the given range (bounds are included).
+	 */
+	public static boolean inRangeOf(double val, NumberRange<Double> range) {
+		return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
+	}
+
+	/**
+	 * Checks if the given value is contained in the given range (bounds are included).
+	 */
+	public static boolean inRangeOf(float val, NumberRange<Float> range) {
+		return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
+	}
+
+	/**
+	 * Checks if the given value is contained in the given range (bounds are included).
+	 */
+	public static boolean inRangeOf(int val, NumberRange<Integer> range) {
+		return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
+	}
+
+	/**
+	 * Checks if the given value is contained in the given range (bounds are included).
+	 */
+	public static boolean inRangeOf(long val, NumberRange<Long> range) {
+		return Math.max(range.getMin(), val) == Math.min(val, range.getMax());
+	}
+
+	/**
+	 * Checks if the given value is contained in any of the given ranges (bounds are included).
+	 */
+	public static boolean inRangeOf(double val, List<NumberRange<Double>> ranges) {
+		return ranges.stream().anyMatch(range -> inRangeOf(val, range));
+	}
+
+	/**
+	 * Checks if the given value is contained in any of the given ranges (bounds are included).
+	 */
+	public static boolean inRangeOf(float val, List<NumberRange<Float>> ranges) {
+		return ranges.stream().anyMatch(range -> inRangeOf(val, range));
+	}
+
+	/**
+	 * Checks if the given value is contained in any of the given ranges (bounds are included).
+	 */
+	public static boolean inRangeOf(int val, List<NumberRange<Integer>> ranges) {
+		return ranges.stream().anyMatch(range -> inRangeOf(val, range));
+	}
+
+	/**
+	 * Checks if the given value is contained in any of the given ranges (bounds are included).
+	 */
+	public static boolean inRangeOf(long val, List<NumberRange<Long>> ranges) {
+		return ranges.stream().anyMatch(range -> inRangeOf(val, range));
+	}
+
+	/**
+	 * Expands a range of integers to a List of integers.
+	 */
+	public static List<Integer> expandRange(NumberRange<Integer> range) {
+		return IntStream.rangeClosed(range.getMin(), range.getMax()).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
+	}
+
+	/**
+	 * Expands a range of integers to a List of integers.
+	 */
+	public static List<Integer> expandRange(int min, int max) {
+		return IntStream.rangeClosed(min, max).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
+	}
+
+	/**
+	 * Expands a range of integers to a Set of integers.
+	 */
+	public static Set<Integer> expandRangeToSet(NumberRange<Integer> range) {
+		return IntStream.rangeClosed(range.getMin(), range.getMax()).collect(HashSet::new, HashSet::add, HashSet::addAll);
+	}
+
+	/**
+	 * Expands a range of integers to a Set of integers.
+	 */
+	public static Set<Integer> expandRangeToSet(int min, int max) {
+		return IntStream.rangeClosed(min, max).collect(HashSet::new, HashSet::add, HashSet::addAll);
+	}
+
+	/**
+	 * Expands a range of integers to an array of integers.
+	 */
+	public static Integer[] expandRangeToArray(int min, int max) {
+		return IntStream.rangeClosed(min, max).boxed().toArray(Integer[]::new);
+	}
 }

+ 81 - 81
materialfx/src/main/java/io/github/palexdev/materialfx/beans/PopupPositionBean.java

@@ -15,65 +15,65 @@ import javafx.scene.Node;
  * all info about the content are available so this bean is necessary to properly reposition and animate the popup.
  */
 public class PopupPositionBean {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final Node owner;
-    private final Bounds ownerBounds;
-    private final PositionBean positionBean;
-    private final Alignment alignment;
-    private final double xOffset;
-    private final double yOffset;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public PopupPositionBean(Node owner, PositionBean positionBean, Alignment alignment, double xOffset, double yOffset) {
-        this.owner = owner;
-        this.ownerBounds = owner.getLayoutBounds();
-        this.positionBean = positionBean;
-        this.alignment = alignment;
-        this.xOffset = xOffset;
-        this.yOffset = yOffset;
-    }
-
-    /**
-     * @return the popup's owner
-     */
-    public Node getOwner() {
-        return owner;
-    }
-
-    /**
-     * @return the popup owner's bounds
-     */
-    public Bounds getOwnerBounds() {
-        return ownerBounds;
-    }
-
-    /**
-     * @return the popup owner's width
-     */
-    public double getOwnerWidth() {
-        return ownerBounds.getWidth();
-    }
-
-    /**
-     * @return the popup owner's height
-     */
-    public double getOwnerHeight() {
-        return ownerBounds.getHeight();
-    }
-
-    /**
-     * You should NOT rely on these coordinates since as of now
-     * they do not take into account the translations made by the skin.
-     *
-     * @return the initial computed coordinates of the popup
-     */
-    public PositionBean getPositionBean() {
-	    return positionBean;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final Node owner;
+	private final Bounds ownerBounds;
+	private final PositionBean positionBean;
+	private final Alignment alignment;
+	private final double xOffset;
+	private final double yOffset;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public PopupPositionBean(Node owner, PositionBean positionBean, Alignment alignment, double xOffset, double yOffset) {
+		this.owner = owner;
+		this.ownerBounds = owner.getLayoutBounds();
+		this.positionBean = positionBean;
+		this.alignment = alignment;
+		this.xOffset = xOffset;
+		this.yOffset = yOffset;
+	}
+
+	/**
+	 * @return the popup's owner
+	 */
+	public Node getOwner() {
+		return owner;
+	}
+
+	/**
+	 * @return the popup owner's bounds
+	 */
+	public Bounds getOwnerBounds() {
+		return ownerBounds;
+	}
+
+	/**
+	 * @return the popup owner's width
+	 */
+	public double getOwnerWidth() {
+		return ownerBounds.getWidth();
+	}
+
+	/**
+	 * @return the popup owner's height
+	 */
+	public double getOwnerHeight() {
+		return ownerBounds.getHeight();
+	}
+
+	/**
+	 * You should NOT rely on these coordinates since as of now
+	 * they do not take into account the translations made by the skin.
+	 *
+	 * @return the initial computed coordinates of the popup
+	 */
+	public PositionBean getPositionBean() {
+		return positionBean;
+	}
 
 	/**
 	 * Delegate for {@link #getPositionBean()}.getX().
@@ -112,26 +112,26 @@ public class PopupPositionBean {
 	 */
 	public HPos getHPos() {
 		return alignment.getHPos();
-    }
-
-    /**
-     * @return the specified {@link VPos}
-     */
-    public VPos getVPos() {
-        return alignment.getVPos();
-    }
-
-    /**
-     * @return the specified x offset
-     */
-    public double getXOffset() {
-        return xOffset;
-    }
-
-    /**
-     * @return the specified y offset
-     */
-    public double getYOffset() {
-        return yOffset;
-    }
+	}
+
+	/**
+	 * @return the specified {@link VPos}
+	 */
+	public VPos getVPos() {
+		return alignment.getVPos();
+	}
+
+	/**
+	 * @return the specified x offset
+	 */
+	public double getXOffset() {
+		return xOffset;
+	}
+
+	/**
+	 * @return the specified y offset
+	 */
+	public double getYOffset() {
+		return yOffset;
+	}
 }

+ 34 - 34
materialfx/src/main/java/io/github/palexdev/materialfx/beans/PositionBean.java

@@ -32,19 +32,19 @@ public class PositionBean {
 	//================================================================================
 	// Properties
 	//================================================================================
-    private final DoubleProperty x = new SimpleDoubleProperty(0);
-    private final DoubleProperty y = new SimpleDoubleProperty(0);
+	private final DoubleProperty x = new SimpleDoubleProperty(0);
+	private final DoubleProperty y = new SimpleDoubleProperty(0);
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public PositionBean() {
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public PositionBean() {
+	}
 
-    public PositionBean(double x, double y) {
-        setX(x);
-	    setY(y);
-    }
+	public PositionBean(double x, double y) {
+		setX(x);
+		setY(y);
+	}
 
 	//================================================================================
 	// Static Methods
@@ -83,27 +83,27 @@ public class PositionBean {
 
 	/**
 	 * The x coordinate property.
-     */
-    public DoubleProperty xProperty() {
-        return x;
-    }
-
-    public void setX(double xPosition) {
-        this.x.set(xPosition);
-    }
-
-    public double getY() {
-        return y.get();
-    }
-
-    /**
-     * The y coordinate property
-     */
-    public DoubleProperty yProperty() {
-        return y;
-    }
-
-    public void setY(double yPosition) {
-        this.y.set(yPosition);
-    }
+	 */
+	public DoubleProperty xProperty() {
+		return x;
+	}
+
+	public void setX(double xPosition) {
+		this.x.set(xPosition);
+	}
+
+	public double getY() {
+		return y.get();
+	}
+
+	/**
+	 * The y coordinate property
+	 */
+	public DoubleProperty yProperty() {
+		return y;
+	}
+
+	public void setY(double yPosition) {
+		this.y.set(yPosition);
+	}
 }

+ 46 - 46
materialfx/src/main/java/io/github/palexdev/materialfx/beans/TransitionPositionBean.java

@@ -28,57 +28,57 @@ import javafx.animation.Transition;
  * </pre>
  */
 public class TransitionPositionBean extends PositionBean {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final double endX;
-    private final double endY;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final double endX;
+	private final double endY;
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public TransitionPositionBean(double x, double y, double endX, double endY) {
-        super(x, y);
-        this.endX = endX;
-        this.endY = endY;
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public TransitionPositionBean(double x, double y, double endX, double endY) {
+		super(x, y);
+		this.endX = endX;
+		this.endY = endY;
+	}
 
-    //================================================================================
-    // Static Methods
-    //================================================================================
-    public static TransitionPositionBean of(double x, double y, double endX, double endY) {
-        return new TransitionPositionBean(x, y, endX, endY);
-    }
+	//================================================================================
+	// Static Methods
+	//================================================================================
+	public static TransitionPositionBean of(double x, double y, double endX, double endY) {
+		return new TransitionPositionBean(x, y, endX, endY);
+	}
 
-    //================================================================================
-    // Getters/Setters
-    //================================================================================
+	//================================================================================
+	// Getters/Setters
+	//================================================================================
 
-    /**
-     * @return the end x coordinate
-     */
-    public double getEndX() {
-        return endX;
-    }
+	/**
+	 * @return the end x coordinate
+	 */
+	public double getEndX() {
+		return endX;
+	}
 
-    /**
-     * @return the end y coordinate
-     */
-    public double getEndY() {
-        return endY;
-    }
+	/**
+	 * @return the end y coordinate
+	 */
+	public double getEndY() {
+		return endY;
+	}
 
-    /**
-     * @return the difference between the star x and end x coordinates
-     */
-    public double deltaX() {
-        return getX() - getEndX();
-    }
+	/**
+	 * @return the difference between the star x and end x coordinates
+	 */
+	public double deltaX() {
+		return getX() - getEndX();
+	}
 
-    /**
-     * @return the difference between the start y and end y coordinates
-     */
-    public double deltaY() {
-        return getY() - getEndY();
-    }
+	/**
+	 * @return the difference between the start y and end y coordinates
+	 */
+	public double deltaY() {
+		return getY() - getEndY();
+	}
 }

+ 24 - 24
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/NumberRangeProperty.java

@@ -49,31 +49,31 @@ public class NumberRangeProperty<T extends Number> extends SimpleObjectProperty<
 		return get() == null ? null : get().getMin();
 	}
 
-    /**
-     * Convenience method to set a range with both min and max equal.
-     */
-    public void setRange(T value) {
-        set(NumberRange.of(value));
-    }
+	/**
+	 * Convenience method to set a range with both min and max equal.
+	 */
+	public void setRange(T value) {
+		set(NumberRange.of(value));
+	}
 
-    /**
-     * Convenience method to set a range with the given min and max values.
-     */
-    public void setRange(T min, T max) {
-        set(NumberRange.of(min, max));
-    }
+	/**
+	 * Convenience method to set a range with the given min and max values.
+	 */
+	public void setRange(T min, T max) {
+		set(NumberRange.of(min, max));
+	}
 
-    //================================================================================
-    // Overridden Methods
-    //================================================================================
+	//================================================================================
+	// Overridden Methods
+	//================================================================================
 
-    /**
-     * Overridden to check equality between ranges and return in case ranges are the same.
-     */
-    @Override
-    public void set(NumberRange<T> newValue) {
-        NumberRange<T> oldValue = get();
-        if (newValue.equals(oldValue)) return;
-        super.set(newValue);
-    }
+	/**
+	 * Overridden to check equality between ranges and return in case ranges are the same.
+	 */
+	@Override
+	public void set(NumberRange<T> newValue) {
+		NumberRange<T> oldValue = get();
+		if (newValue.equals(oldValue)) return;
+		super.set(newValue);
+	}
 }

+ 29 - 28
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/base/ResettableProperty.java

@@ -22,36 +22,37 @@ import javafx.beans.property.Property;
 
 /**
  * Base interface for all resettable properties.
+ *
  * @param <T>
  */
 public interface ResettableProperty<T> extends Property<T> {
 
-    /**
-     * Sets the property's value to the default value.
-     */
-    default void reset() {
-        setValue(getDefaultValue());
-    }
-
-    boolean isFireChangeOnReset();
-
-    /**
-     * Specifies if the property should fire a change event when it is reset or not.
-     */
-    void setFireChangeOnReset(boolean fireChangeOnReset);
-
-    /**
-     * Specifies if the property has been reset.
-     */
-    boolean hasBeenReset();
-
-    /**
-     * @return the property's default value
-     */
-    T getDefaultValue();
-
-    /**
-     * Sets the property's default value to the given value.
-     */
-    void setDefaultValue(T defaultValue);
+	/**
+	 * Sets the property's value to the default value.
+	 */
+	default void reset() {
+		setValue(getDefaultValue());
+	}
+
+	boolean isFireChangeOnReset();
+
+	/**
+	 * Specifies if the property should fire a change event when it is reset or not.
+	 */
+	void setFireChangeOnReset(boolean fireChangeOnReset);
+
+	/**
+	 * Specifies if the property has been reset.
+	 */
+	boolean hasBeenReset();
+
+	/**
+	 * @return the property's default value
+	 */
+	T getDefaultValue();
+
+	/**
+	 * Sets the property's default value to the given value.
+	 */
+	void setDefaultValue(T defaultValue);
 }

+ 65 - 65
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/base/SynchronizedProperty.java

@@ -92,74 +92,74 @@ import java.util.function.Supplier;
  */
 public interface SynchronizedProperty<T> extends Property<T> {
 
-    /**
-     * Sets this property's state to "waiting" then uses {@link ExecutionUtils#executeWhen(Observable, Runnable, boolean, Supplier, boolean)}
-     * to "awake" the property when the given observable changes.
-     * <p></p>
-     * Just like JavaFX properties if the new value is the same as the current value the method returns and does nothing.
-     *
-     * @param value      the new value of the property
-     * @param observable the observable to wait for
-     * @throws IllegalArgumentException if the given observable is the property itself or if the passed observable
-     *                                  is another SynchronizedProperty, and it is already waiting for some other observable
-     * @throws IllegalStateException    if this property is already waiting for another observable
-     */
-    void setAndWait(T value, ObservableValue<?> observable);
+	/**
+	 * Sets this property's state to "waiting" then uses {@link ExecutionUtils#executeWhen(Observable, Runnable, boolean, Supplier, boolean)}
+	 * to "awake" the property when the given observable changes.
+	 * <p></p>
+	 * Just like JavaFX properties if the new value is the same as the current value the method returns and does nothing.
+	 *
+	 * @param value      the new value of the property
+	 * @param observable the observable to wait for
+	 * @throws IllegalArgumentException if the given observable is the property itself or if the passed observable
+	 *                                  is another SynchronizedProperty, and it is already waiting for some other observable
+	 * @throws IllegalStateException    if this property is already waiting for another observable
+	 */
+	void setAndWait(T value, ObservableValue<?> observable);
 
-    /**
-     * @return whether this property is in waiting state
-     */
-    boolean isWaiting();
+	/**
+	 * @return whether this property is in waiting state
+	 */
+	boolean isWaiting();
 
-    /**
-     * @return the waiting state property as a read only property
-     */
-    ReadOnlyBooleanProperty waiting();
+	/**
+	 * @return the waiting state property as a read only property
+	 */
+	ReadOnlyBooleanProperty waiting();
 
-    /**
-     * Awakes the property by setting {@link #waiting()} to false.
-     * <p></p>
-     * This method should never be invoked by the user, the awakening is automatically
-     * managed by the property. If for some reason the property stays in waiting state you
-     * are probably doing something wrong.
-     */
-    void awake();
+	/**
+	 * Awakes the property by setting {@link #waiting()} to false.
+	 * <p></p>
+	 * This method should never be invoked by the user, the awakening is automatically
+	 * managed by the property. If for some reason the property stays in waiting state you
+	 * are probably doing something wrong.
+	 */
+	void awake();
 
-    /**
-     * Helper class to avoid code duplication.
-     */
-    class Helper {
+	/**
+	 * Helper class to avoid code duplication.
+	 */
+	class Helper {
 
-        /**
-         * Check some parameters before proceeding with the set and wait method
-         *
-         * @param value      the new value of the property
-         * @param observable the observable to wait for
-         * @return whether the check failed
-         * @throws IllegalArgumentException if the given observable is the property itself or if the passed observable
-         *                                  is another SynchronizedProperty, and it is already waiting for some other observable
-         * @throws IllegalStateException    if the property is bound unidirectionally, or
-         *                                  if this property is already waiting for another observable
-         */
-        public static <T> boolean check(SynchronizedProperty<T> property, T value, ObservableValue<?> observable) {
-            if (observable == property) {
-                throw new IllegalArgumentException("The passed property cannot be the same as this!" +
-                        " Proceeding with this method would lead to a deadlock.");
-            }
-            if (property.isBound()) {
-                throw new IllegalStateException("A bound value cannot be set!");
-            }
-            if (property.isWaiting()) {
-                throw new IllegalStateException("The property is already waiting for some other observable!");
-            }
-            if (observable instanceof SynchronizedProperty) {
-                SynchronizedProperty<?> synchronizedProperty = (SynchronizedProperty<?>) observable;
-                if (synchronizedProperty.isWaiting()) {
-                    throw new IllegalArgumentException("The passed property is already waiting for some other property!" +
-                            " Proceeding with this method would lead to a deadlock.");
-                }
-            }
-            return property.getValue() == null || !property.getValue().equals(value);
-        }
-    }
+		/**
+		 * Check some parameters before proceeding with the set and wait method
+		 *
+		 * @param value      the new value of the property
+		 * @param observable the observable to wait for
+		 * @return whether the check failed
+		 * @throws IllegalArgumentException if the given observable is the property itself or if the passed observable
+		 *                                  is another SynchronizedProperty, and it is already waiting for some other observable
+		 * @throws IllegalStateException    if the property is bound unidirectionally, or
+		 *                                  if this property is already waiting for another observable
+		 */
+		public static <T> boolean check(SynchronizedProperty<T> property, T value, ObservableValue<?> observable) {
+			if (observable == property) {
+				throw new IllegalArgumentException("The passed property cannot be the same as this!" +
+						" Proceeding with this method would lead to a deadlock.");
+			}
+			if (property.isBound()) {
+				throw new IllegalStateException("A bound value cannot be set!");
+			}
+			if (property.isWaiting()) {
+				throw new IllegalStateException("The property is already waiting for some other observable!");
+			}
+			if (observable instanceof SynchronizedProperty) {
+				SynchronizedProperty<?> synchronizedProperty = (SynchronizedProperty<?>) observable;
+				if (synchronizedProperty.isWaiting()) {
+					throw new IllegalArgumentException("The passed property is already waiting for some other property!" +
+							" Proceeding with this method would lead to a deadlock.");
+				}
+			}
+			return property.getValue() == null || !property.getValue().equals(value);
+		}
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableBooleanProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleBooleanProperty;
  * A {@link SimpleBooleanProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableBooleanProperty extends SimpleBooleanProperty implements ResettableProperty<Boolean> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private boolean defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableBooleanProperty() {
-    }
-
-    public ResettableBooleanProperty(boolean initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableBooleanProperty(boolean initialValue, boolean defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableBooleanProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableBooleanProperty(Object bean, String name, boolean initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableBooleanProperty(Object bean, String name, boolean initialValue, boolean defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(boolean newValue) {
-        hasBeenReset = newValue == defaultValue;
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue() == defaultValue && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public Boolean getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(Boolean defaultValue) {
-        this.defaultValue = defaultValue;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private boolean defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableBooleanProperty() {
+	}
+
+	public ResettableBooleanProperty(boolean initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableBooleanProperty(boolean initialValue, boolean defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableBooleanProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableBooleanProperty(Object bean, String name, boolean initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableBooleanProperty(Object bean, String name, boolean initialValue, boolean defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(boolean newValue) {
+		hasBeenReset = newValue == defaultValue;
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue() == defaultValue && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public Boolean getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(Boolean defaultValue) {
+		this.defaultValue = defaultValue;
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableDoubleProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleDoubleProperty;
  * A {@link SimpleDoubleProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableDoubleProperty extends SimpleDoubleProperty implements ResettableProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private double defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableDoubleProperty() {
-    }
-
-    public ResettableDoubleProperty(double initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableDoubleProperty(double initialValue, double defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableDoubleProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableDoubleProperty(Object bean, String name, double initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableDoubleProperty(Object bean, String name, double initialValue, Double defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(double newValue) {
-        hasBeenReset = newValue == defaultValue;
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue() == defaultValue && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public Double getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(Number defaultValue) {
-        this.defaultValue = defaultValue.doubleValue();
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private double defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableDoubleProperty() {
+	}
+
+	public ResettableDoubleProperty(double initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableDoubleProperty(double initialValue, double defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableDoubleProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableDoubleProperty(Object bean, String name, double initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableDoubleProperty(Object bean, String name, double initialValue, Double defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(double newValue) {
+		hasBeenReset = newValue == defaultValue;
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue() == defaultValue && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public Double getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(Number defaultValue) {
+		this.defaultValue = defaultValue.doubleValue();
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableFloatProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleFloatProperty;
  * A {@link SimpleFloatProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableFloatProperty extends SimpleFloatProperty implements ResettableProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private float defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableFloatProperty() {
-    }
-
-    public ResettableFloatProperty(float initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableFloatProperty(float initialValue, float defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableFloatProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableFloatProperty(Object bean, String name, float initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableFloatProperty(Object bean, String name, float initialValue, Float defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(float newValue) {
-        hasBeenReset = newValue == defaultValue;
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue() == defaultValue && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public Float getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(Number defaultValue) {
-        this.defaultValue = defaultValue.floatValue();
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private float defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableFloatProperty() {
+	}
+
+	public ResettableFloatProperty(float initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableFloatProperty(float initialValue, float defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableFloatProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableFloatProperty(Object bean, String name, float initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableFloatProperty(Object bean, String name, float initialValue, Float defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(float newValue) {
+		hasBeenReset = newValue == defaultValue;
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue() == defaultValue && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public Float getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(Number defaultValue) {
+		this.defaultValue = defaultValue.floatValue();
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableIntegerProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleIntegerProperty;
  * A {@link SimpleIntegerProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableIntegerProperty extends SimpleIntegerProperty implements ResettableProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private int defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableIntegerProperty() {
-    }
-
-    public ResettableIntegerProperty(int initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableIntegerProperty(int initialValue, int defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableIntegerProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableIntegerProperty(Object bean, String name, int initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableIntegerProperty(Object bean, String name, int initialValue, int defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(int newValue) {
-        hasBeenReset = newValue == defaultValue;
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue() == defaultValue && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public Integer getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(Number defaultValue) {
-        this.defaultValue = defaultValue.intValue();
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private int defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableIntegerProperty() {
+	}
+
+	public ResettableIntegerProperty(int initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableIntegerProperty(int initialValue, int defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableIntegerProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableIntegerProperty(Object bean, String name, int initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableIntegerProperty(Object bean, String name, int initialValue, int defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(int newValue) {
+		hasBeenReset = newValue == defaultValue;
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue() == defaultValue && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public Integer getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(Number defaultValue) {
+		this.defaultValue = defaultValue.intValue();
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableLongProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleLongProperty;
  * A {@link SimpleLongProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableLongProperty extends SimpleLongProperty implements ResettableProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private long defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableLongProperty() {
-    }
-
-    public ResettableLongProperty(long initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableLongProperty(long initialValue, long defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableLongProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableLongProperty(Object bean, String name, long initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableLongProperty(Object bean, String name, long initialValue, long defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(long newValue) {
-        hasBeenReset = newValue == defaultValue;
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue() == defaultValue && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public Long getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(Number defaultValue) {
-        this.defaultValue = defaultValue.longValue();
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private long defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableLongProperty() {
+	}
+
+	public ResettableLongProperty(long initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableLongProperty(long initialValue, long defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableLongProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableLongProperty(Object bean, String name, long initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableLongProperty(Object bean, String name, long initialValue, long defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(long newValue) {
+		hasBeenReset = newValue == defaultValue;
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue() == defaultValue && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public Long getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(Number defaultValue) {
+		this.defaultValue = defaultValue.longValue();
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableObjectProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleObjectProperty;
  * A {@link SimpleObjectProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableObjectProperty<T> extends SimpleObjectProperty<T> implements ResettableProperty<T> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private T defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableObjectProperty() {
-    }
-
-    public ResettableObjectProperty(T initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableObjectProperty(T initialValue, T defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableObjectProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableObjectProperty(Object bean, String name, T initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableObjectProperty(Object bean, String name, T initialValue, T defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(T newValue) {
-        hasBeenReset = newValue == defaultValue;
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue().equals(defaultValue) && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public T getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(T defaultValue) {
-        this.defaultValue = defaultValue;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private T defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableObjectProperty() {
+	}
+
+	public ResettableObjectProperty(T initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableObjectProperty(T initialValue, T defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableObjectProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableObjectProperty(Object bean, String name, T initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableObjectProperty(Object bean, String name, T initialValue, T defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(T newValue) {
+		hasBeenReset = newValue == defaultValue;
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue().equals(defaultValue) && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public T getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(T defaultValue) {
+		this.defaultValue = defaultValue;
+	}
 }

+ 77 - 77
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/resettable/ResettableStringProperty.java

@@ -25,81 +25,81 @@ import javafx.beans.property.SimpleStringProperty;
  * A {@link SimpleStringProperty} that implements {@link ResettableProperty}.
  */
 public class ResettableStringProperty extends SimpleStringProperty implements ResettableProperty<String> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private String defaultValue;
-    private boolean fireChangeOnReset = false;
-    private boolean hasBeenReset = false;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ResettableStringProperty() {
-    }
-
-    public ResettableStringProperty(String initialValue) {
-        super(initialValue);
-    }
-
-    public ResettableStringProperty(String initialValue, String defaultValue) {
-        super(initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    public ResettableStringProperty(Object bean, String name) {
-        super(bean, name);
-    }
-
-    public ResettableStringProperty(Object bean, String name, String initialValue) {
-        super(bean, name, initialValue);
-    }
-
-    public ResettableStringProperty(Object bean, String name, String initialValue, String defaultValue) {
-        super(bean, name, initialValue);
-        this.defaultValue = defaultValue;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    public boolean isFireChangeOnReset() {
-        return fireChangeOnReset;
-    }
-
-    @Override
-    public void setFireChangeOnReset(boolean fireChangeOnReset) {
-        this.fireChangeOnReset = fireChangeOnReset;
-    }
-
-    @Override
-    public void set(String newValue) {
-        hasBeenReset = newValue.equals(defaultValue);
-        super.set(newValue);
-    }
-
-    @Override
-    protected void fireValueChangedEvent() {
-        if (getValue().equals(defaultValue) && !fireChangeOnReset) {
-            return;
-        }
-
-        super.fireValueChangedEvent();
-    }
-
-    @Override
-    public boolean hasBeenReset() {
-        return hasBeenReset;
-    }
-
-    @Override
-    public String getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public void setDefaultValue(String defaultValue) {
-        this.defaultValue = defaultValue;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private String defaultValue;
+	private boolean fireChangeOnReset = false;
+	private boolean hasBeenReset = false;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ResettableStringProperty() {
+	}
+
+	public ResettableStringProperty(String initialValue) {
+		super(initialValue);
+	}
+
+	public ResettableStringProperty(String initialValue, String defaultValue) {
+		super(initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	public ResettableStringProperty(Object bean, String name) {
+		super(bean, name);
+	}
+
+	public ResettableStringProperty(Object bean, String name, String initialValue) {
+		super(bean, name, initialValue);
+	}
+
+	public ResettableStringProperty(Object bean, String name, String initialValue, String defaultValue) {
+		super(bean, name, initialValue);
+		this.defaultValue = defaultValue;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	public boolean isFireChangeOnReset() {
+		return fireChangeOnReset;
+	}
+
+	@Override
+	public void setFireChangeOnReset(boolean fireChangeOnReset) {
+		this.fireChangeOnReset = fireChangeOnReset;
+	}
+
+	@Override
+	public void set(String newValue) {
+		hasBeenReset = newValue.equals(defaultValue);
+		super.set(newValue);
+	}
+
+	@Override
+	protected void fireValueChangedEvent() {
+		if (getValue().equals(defaultValue) && !fireChangeOnReset) {
+			return;
+		}
+
+		super.fireValueChangedEvent();
+	}
+
+	@Override
+	public boolean hasBeenReset() {
+		return hasBeenReset;
+	}
+
+	@Override
+	public String getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public void setDefaultValue(String defaultValue) {
+		this.defaultValue = defaultValue;
+	}
 }

+ 16 - 16
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/styleable/StyleableBooleanProperty.java

@@ -7,24 +7,24 @@ import javafx.css.Styleable;
 
 public class StyleableBooleanProperty extends SimpleStyleableBooleanProperty {
 
-    public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData) {
-        super(cssMetaData);
-    }
+	public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData) {
+		super(cssMetaData);
+	}
 
-    public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, boolean initialValue) {
-        super(cssMetaData, initialValue);
-    }
+	public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, boolean initialValue) {
+		super(cssMetaData, initialValue);
+	}
 
-    public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, Object bean, String name) {
-        super(cssMetaData, bean, name);
-    }
+	public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, Object bean, String name) {
+		super(cssMetaData, bean, name);
+	}
 
-    public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, Object bean, String name, boolean initialValue) {
-        super(cssMetaData, bean, name, initialValue);
-    }
+	public StyleableBooleanProperty(CssMetaData<? extends Styleable, Boolean> cssMetaData, Object bean, String name, boolean initialValue) {
+		super(cssMetaData, bean, name, initialValue);
+	}
 
-    @Override
-    public StyleOrigin getStyleOrigin() {
-        return StyleOrigin.USER_AGENT;
-    }
+	@Override
+	public StyleOrigin getStyleOrigin() {
+		return StyleOrigin.USER_AGENT;
+	}
 }

+ 184 - 184
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedBooleanProperty.java

@@ -33,188 +33,188 @@ import javafx.beans.value.ObservableValue;
  * Implementation of {@link SynchronizedProperty} for boolean values.
  */
 public class SynchronizedBooleanProperty extends SimpleBooleanProperty implements SynchronizedProperty<Boolean> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedBooleanProperty() {
-        initialize();
-    }
-
-    public SynchronizedBooleanProperty(boolean initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedBooleanProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedBooleanProperty(Object bean, String name, boolean initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(Boolean value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional binding with the given observable.
-     * <p>
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends Boolean> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<Boolean> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */
-    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<Boolean> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        BindingManager bindingManager = BindingManager.instance();
-        return bindingManager.isBound(this) && !bindingManager.isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedBooleanProperty() {
+		initialize();
+	}
+
+	public SynchronizedBooleanProperty(boolean initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedBooleanProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedBooleanProperty(Object bean, String name, boolean initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(Boolean value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional binding with the given observable.
+	 * <p>
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends Boolean> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<Boolean> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<Boolean> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		BindingManager bindingManager = BindingManager.instance();
+		return bindingManager.isBound(this) && !bindingManager.isIgnoreBinding(this);
+	}
 }

+ 183 - 183
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedDoubleProperty.java

@@ -33,187 +33,187 @@ import javafx.beans.value.ObservableValue;
  * Implementation of {@link SynchronizedProperty} for double values.
  */
 public class SynchronizedDoubleProperty extends SimpleDoubleProperty implements SynchronizedProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedDoubleProperty() {
-        initialize();
-    }
-
-    public SynchronizedDoubleProperty(double initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedDoubleProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedDoubleProperty(Object bean, String name, double initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(Number value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value.doubleValue());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional bindings with the given observable.
-     * <p>
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends Number> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<Number> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */
-    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<Number> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedDoubleProperty() {
+		initialize();
+	}
+
+	public SynchronizedDoubleProperty(double initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedDoubleProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedDoubleProperty(Object bean, String name, double initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(Number value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value.doubleValue());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional bindings with the given observable.
+	 * <p>
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends Number> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<Number> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<Number> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
+	}
 }

+ 183 - 183
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedFloatProperty.java

@@ -33,187 +33,187 @@ import javafx.beans.value.ObservableValue;
  * Implementation of {@link SynchronizedProperty} for float values.
  */
 public class SynchronizedFloatProperty extends SimpleFloatProperty implements SynchronizedProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedFloatProperty() {
-        initialize();
-    }
-
-    public SynchronizedFloatProperty(float initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedFloatProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedFloatProperty(Object bean, String name, float initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(Number value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value.floatValue());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional bindings with the given observable.
-     * <p>
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends Number> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<Number> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */
-    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<Number> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedFloatProperty() {
+		initialize();
+	}
+
+	public SynchronizedFloatProperty(float initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedFloatProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedFloatProperty(Object bean, String name, float initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(Number value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value.floatValue());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional bindings with the given observable.
+	 * <p>
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends Number> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<Number> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<Number> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
+	}
 }

+ 183 - 183
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedIntegerProperty.java

@@ -33,187 +33,187 @@ import javafx.beans.value.ObservableValue;
  * Implementation of {@link SynchronizedProperty} for integer values.
  */
 public class SynchronizedIntegerProperty extends ReadOnlyIntegerWrapper implements SynchronizedProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedIntegerProperty() {
-        initialize();
-    }
-
-    public SynchronizedIntegerProperty(int initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedIntegerProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedIntegerProperty(Object bean, String name, int initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(Number value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value.intValue());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional bindings with the given observable.
-     * <p>
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends Number> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<Number> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */
-    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<Number> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedIntegerProperty() {
+		initialize();
+	}
+
+	public SynchronizedIntegerProperty(int initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedIntegerProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedIntegerProperty(Object bean, String name, int initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(Number value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value.intValue());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional bindings with the given observable.
+	 * <p>
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends Number> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<Number> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<Number> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
+	}
 }

+ 182 - 182
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedLongProperty.java

@@ -33,186 +33,186 @@ import javafx.beans.value.ObservableValue;
  * Implementation of {@link SynchronizedProperty} for long values.
  */
 public class SynchronizedLongProperty extends SimpleLongProperty implements SynchronizedProperty<Number> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedLongProperty() {
-        initialize();
-    }
-
-    public SynchronizedLongProperty(long initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedLongProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedLongProperty(Object bean, String name, long initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(Number value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value.longValue());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional bindings with the given observable.
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends Number> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<Number> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */
-    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<Number> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedLongProperty() {
+		initialize();
+	}
+
+	public SynchronizedLongProperty(long initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedLongProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedLongProperty(Object bean, String name, long initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(Number value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value.longValue());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional bindings with the given observable.
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends Number> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<Number> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<Number> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
+	}
 }

+ 183 - 182
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedObjectProperty.java

@@ -35,186 +35,187 @@ import javafx.beans.value.ObservableValue;
  * @param <T> the type of the wrapped Object
  */
 public class SynchronizedObjectProperty<T> extends ReadOnlyObjectWrapper<T> implements SynchronizedProperty<T> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedObjectProperty() {
-        initialize();
-    }
-
-    public SynchronizedObjectProperty(T initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedObjectProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedObjectProperty(Object bean, String name, T initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(T value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional bindings with the given observable.
-     * <p>
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends T> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<T> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<T> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedObjectProperty() {
+		initialize();
+	}
+
+	public SynchronizedObjectProperty(T initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedObjectProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedObjectProperty(Object bean, String name, T initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(T value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional bindings with the given observable.
+	 * <p>
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends T> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<T> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<T> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
+	}
 }

+ 183 - 183
materialfx/src/main/java/io/github/palexdev/materialfx/beans/properties/synced/SynchronizedStringProperty.java

@@ -33,187 +33,187 @@ import javafx.beans.value.ObservableValue;
  * Implementation of {@link SynchronizedProperty} for String values.
  */
 public class SynchronizedStringProperty extends SimpleStringProperty implements SynchronizedProperty<String> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public SynchronizedStringProperty() {
-        initialize();
-    }
-
-    public SynchronizedStringProperty(String initialValue) {
-        super(initialValue);
-        initialize();
-    }
-
-    public SynchronizedStringProperty(Object bean, String name) {
-        super(bean, name);
-        initialize();
-    }
-
-    public SynchronizedStringProperty(Object bean, String name, String initialValue) {
-        super(bean, name, initialValue);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
-     * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
-     */
-    private void initialize() {
-        ExecutionUtils.executeWhen(
-                waiting,
-                () -> {},
-                this::fireValueChangedEvent,
-                false,
-                false,
-                false,
-                false
-        );
-    }
-
-    //================================================================================
-    // Implemented/Overridden Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setAndWait(String value, ObservableValue<?> observable) {
-        if (!Helper.check(this, value, observable)) return;
-
-        waiting.set(true);
-        ExecutionUtils.executeWhen(
-                observable,
-                this::awake,
-                false,
-                () -> true,
-                true
-        );
-        set(value);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isWaiting() {
-        return waiting.get();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ReadOnlyBooleanProperty waiting() {
-        return waiting.getReadOnlyProperty();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void awake() {
-        waiting.set(false);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Overridden to not fire a change event if {@link #waiting()} is true.
-     */
-    @Override
-    protected void fireValueChangedEvent() {
-        if (isWaiting()) return;
-        super.fireValueChangedEvent();
-    }
-
-    //================================================================================
-    // Binding
-    //================================================================================
-
-    /**
-     * Creates a unidirectional bindings with the given observable.
-     * <p>
-     * The binding is created using the new {@link BindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound it is automatically unbound before bindings to the new observable.
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BindingManager
-     */
-    @Override
-    public void bind(ObservableValue<? extends String> source) {
-        if (this == source) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BindingManager.instance().bind(this).to(source).create();
-    }
-
-    /**
-     * Creates a bidirectional bindings between this property and the given property.
-     * <p>
-     * The binding is created using the new {@link BiBindingManager} mechanism.
-     * <p></p>
-     * If the property is already bound unidirectionally it is automatically unbound.
-     * <p>
-     * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
-     * this way you can have multiple bidirectional bindings
-     *
-     * @throws IllegalArgumentException if the given observable is the property itself
-     * @see BiBindingManager
-     */
-    @Override
-    public void bindBidirectional(Property<String> other) {
-        if (this == other) {
-            throw new IllegalArgumentException("Cannot bind to itself!");
-        }
-
-        if (isBound()) unbind();
-        BiBindingManager.instance().bindBidirectional(this).to(other).create();
-    }
-
-    /**
-     * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
-     */
-    @Override
-    public void unbind() {
-        BindingManager.instance().unbind(this);
-    }
-
-    /**
-     * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
-     */
-    @Override
-    public void unbindBidirectional(Property<String> other) {
-        BiBindingManager.instance().unbind(this, other);
-    }
-
-    /**
-     * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
-     */
-    public void clearBidirectional() {
-        BiBindingManager.instance().disposeFor(this);
-    }
-
-    /**
-     * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
-     *
-     * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
-     */
-    @Override
-    public boolean isBound() {
-        return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ReadOnlyBooleanWrapper waiting = new ReadOnlyBooleanWrapper();
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public SynchronizedStringProperty() {
+		initialize();
+	}
+
+	public SynchronizedStringProperty(String initialValue) {
+		super(initialValue);
+		initialize();
+	}
+
+	public SynchronizedStringProperty(Object bean, String name) {
+		super(bean, name);
+		initialize();
+	}
+
+	public SynchronizedStringProperty(Object bean, String name, String initialValue) {
+		super(bean, name, initialValue);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a listener to the property by calling {@link ExecutionUtils#executeWhen(BooleanExpression, Runnable, Runnable, boolean, boolean, boolean, boolean)}
+	 * to call {@link #fireValueChangedEvent()} when the property is awakened, {@link #awake()}.
+	 */
+	private void initialize() {
+		ExecutionUtils.executeWhen(
+				waiting,
+				() -> {},
+				this::fireValueChangedEvent,
+				false,
+				false,
+				false,
+				false
+		);
+	}
+
+	//================================================================================
+	// Implemented/Overridden Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setAndWait(String value, ObservableValue<?> observable) {
+		if (!Helper.check(this, value, observable)) return;
+
+		waiting.set(true);
+		ExecutionUtils.executeWhen(
+				observable,
+				this::awake,
+				false,
+				() -> true,
+				true
+		);
+		set(value);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isWaiting() {
+		return waiting.get();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public ReadOnlyBooleanProperty waiting() {
+		return waiting.getReadOnlyProperty();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void awake() {
+		waiting.set(false);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Overridden to not fire a change event if {@link #waiting()} is true.
+	 */
+	@Override
+	protected void fireValueChangedEvent() {
+		if (isWaiting()) return;
+		super.fireValueChangedEvent();
+	}
+
+	//================================================================================
+	// Binding
+	//================================================================================
+
+	/**
+	 * Creates a unidirectional bindings with the given observable.
+	 * <p>
+	 * The binding is created using the new {@link BindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound it is automatically unbound before bindings to the new observable.
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BindingManager
+	 */
+	@Override
+	public void bind(ObservableValue<? extends String> source) {
+		if (this == source) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BindingManager.instance().bind(this).to(source).create();
+	}
+
+	/**
+	 * Creates a bidirectional bindings between this property and the given property.
+	 * <p>
+	 * The binding is created using the new {@link BiBindingManager} mechanism.
+	 * <p></p>
+	 * If the property is already bound unidirectionally it is automatically unbound.
+	 * <p>
+	 * If the property is already bound bidirectionally it won't be automatically unbound, just like JavaFX,
+	 * this way you can have multiple bidirectional bindings
+	 *
+	 * @throws IllegalArgumentException if the given observable is the property itself
+	 * @see BiBindingManager
+	 */
+	@Override
+	public void bindBidirectional(Property<String> other) {
+		if (this == other) {
+			throw new IllegalArgumentException("Cannot bind to itself!");
+		}
+
+		if (isBound()) unbind();
+		BiBindingManager.instance().bindBidirectional(this).to(other).create();
+	}
+
+	/**
+	 * Overridden to call {@link BindingManager#unbind(ObservableValue)}.
+	 */
+	@Override
+	public void unbind() {
+		BindingManager.instance().unbind(this);
+	}
+
+	/**
+	 * Overridden to call {@link BiBindingManager#unbind(ObservableValue, ObservableValue)}.
+	 */
+	@Override
+	public void unbindBidirectional(Property<String> other) {
+		BiBindingManager.instance().unbind(this, other);
+	}
+
+	/**
+	 * Delegate method for {@link BiBindingManager#disposeFor(ObservableValue)}.
+	 */
+	public void clearBidirectional() {
+		BiBindingManager.instance().disposeFor(this);
+	}
+
+	/**
+	 * Overridden to check the {@link BindingManager#isBound(ObservableValue)} flag value and {@link BindingManager#isIgnoreBinding(ObservableValue)}.
+	 *
+	 * @return true only if `BindingManager.isBound()` is true and `isIgnoreBound()` is false
+	 */
+	@Override
+	public boolean isBound() {
+		return BindingManager.instance().isBound(this) && !BindingManager.instance().isIgnoreBinding(this);
+	}
 }

+ 5 - 5
materialfx/src/main/java/io/github/palexdev/materialfx/bindings/BiBindingHelper.java

@@ -69,8 +69,8 @@ public class BiBindingHelper<T> extends AbstractBindingHelper<T> {
 	 * <p></p>
 	 * Also calls {@link #beforeBind()} and {@link #afterBind()}.
 	 *
-	 * @param source    the source observable
-	 * @param updater   the {@link BiConsumer} responsible for updating the source when the target changes
+	 * @param source  the source observable
+	 * @param updater the {@link BiConsumer} responsible for updating the source when the target changes
 	 */
 	public BiBindingHelper<T> addSource(ObservableValue<? extends T> source, BiConsumer<T, T> updater) {
 		sources.put(source, updater);
@@ -141,9 +141,9 @@ public class BiBindingHelper<T> extends AbstractBindingHelper<T> {
 	 * The whole process is wrapped in a try-finally block as it's super important to reset
 	 * both the flags at the end.
 	 *
-	 * @param updatingSource    the source that triggered the target update
-	 * @param oldValue          the source's oldValue
-	 * @param newValue          the source's newValue
+	 * @param updatingSource the source that triggered the target update
+	 * @param oldValue       the source's oldValue
+	 * @param newValue       the source's newValue
 	 */
 	@Override
 	protected void updateTarget(ObservableValue<? extends T> updatingSource, T oldValue, T newValue) {

+ 106 - 106
materialfx/src/main/java/io/github/palexdev/materialfx/bindings/BindingHelper.java

@@ -56,121 +56,121 @@ import java.util.function.BiConsumer;
  * @param <T> the properties' value type
  */
 public class BindingHelper<T> extends AbstractBindingHelper<T> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private ObservableValue<? extends T> source;
-    protected boolean ignoreBinding;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private ObservableValue<? extends T> source;
+	protected boolean ignoreBinding;
 
-    //================================================================================
-    // Methods
-    //================================================================================
+	//================================================================================
+	// Methods
+	//================================================================================
 
-    /**
-     * Sets the target to the specified one.
-     */
-    public BindingHelper<T> bind(ObservableValue<? extends T> target) {
-        this.target = target;
-        return this;
-    }
+	/**
+	 * Sets the target to the specified one.
+	 */
+	public BindingHelper<T> bind(ObservableValue<? extends T> target) {
+		this.target = target;
+		return this;
+	}
 
-    /**
-     * Sets the targetUpdater {@link BiConsumer}.
-     */
-    @Override
-    public BindingHelper<T> with(BiConsumer<T, T> targetUpdater) {
-        this.targetUpdater = targetUpdater;
-        return this;
-    }
+	/**
+	 * Sets the targetUpdater {@link BiConsumer}.
+	 */
+	@Override
+	public BindingHelper<T> with(BiConsumer<T, T> targetUpdater) {
+		this.targetUpdater = targetUpdater;
+		return this;
+	}
 
-    /**
-     * Sets the binding source to the given one.
-     * <p>
-     * Also calls {@link #beforeBind()} and {@link #afterBind()}.
-     */
-    public BindingHelper<T> to(ObservableValue<? extends T> source) {
-        this.source = source;
-        beforeBind();
-        source.addListener(sourceListener);
-        afterBind();
-        return this;
-    }
+	/**
+	 * Sets the binding source to the given one.
+	 * <p>
+	 * Also calls {@link #beforeBind()} and {@link #afterBind()}.
+	 */
+	public BindingHelper<T> to(ObservableValue<? extends T> source) {
+		this.source = source;
+		beforeBind();
+		source.addListener(sourceListener);
+		afterBind();
+		return this;
+	}
 
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Sets the 'ignoreBinding' flag to true then calls the super method.
-     * <p>
-     * The whole process is wrapped in a try-finally block since it's as important that the flag
-     * is reset at the end.
-     */
-    @Override
-    protected void updateTarget(ObservableValue<? extends T> source, T oldValue, T newValue) {
-        try {
-            ignoreBinding = true;
-            super.updateTarget(source, oldValue, newValue);
-        } finally {
-            ignoreBinding = false;
-        }
-    }
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Sets the 'ignoreBinding' flag to true then calls the super method.
+	 * <p>
+	 * The whole process is wrapped in a try-finally block since it's as important that the flag
+	 * is reset at the end.
+	 */
+	@Override
+	protected void updateTarget(ObservableValue<? extends T> source, T oldValue, T newValue) {
+		try {
+			ignoreBinding = true;
+			super.updateTarget(source, oldValue, newValue);
+		} finally {
+			ignoreBinding = false;
+		}
+	}
 
-    /**
-     * Causes the target to update with the current source's value.
-     * <p></p>
-     * This is necessary to 'simulate' the JavaFX's eager evaluation of bindings.
-     */
-    public void invalidate() {
-        T value = source.getValue();
-        updateTarget(source, value, value);
-    }
+	/**
+	 * Causes the target to update with the current source's value.
+	 * <p></p>
+	 * This is necessary to 'simulate' the JavaFX's eager evaluation of bindings.
+	 */
+	public void invalidate() {
+		T value = source.getValue();
+		updateTarget(source, value, value);
+	}
 
-    /**
-     * Removes the sourceListener from the source, then
-     * sets the source to null.
-     * <p>
-     * This means that the helper won't be usable anymore until {@link #to(ObservableValue)} is called again.
-     * <p></p>
-     * Also calls {@link #beforeUnbind()}, {@link #afterUnbind()}.
-     */
-    public void unbind() {
-        beforeUnbind();
-        source.removeListener(sourceListener);
-        source = null;
-        afterUnbind();
-    }
+	/**
+	 * Removes the sourceListener from the source, then
+	 * sets the source to null.
+	 * <p>
+	 * This means that the helper won't be usable anymore until {@link #to(ObservableValue)} is called again.
+	 * <p></p>
+	 * Also calls {@link #beforeUnbind()}, {@link #afterUnbind()}.
+	 */
+	public void unbind() {
+		beforeUnbind();
+		source.removeListener(sourceListener);
+		source = null;
+		afterUnbind();
+	}
 
-    /**
-     * Calls {@link #unbind()} and in addition to that
-     * also the target is set to null.
-     * <p>
-     * This means that the helper won't be usable anymore until {@link #bind(ObservableValue)} and
-     * {@link #to(ObservableValue)} are called again.
-     */
-    public void dispose() {
-        unbind();
-        target = null;
-    }
+	/**
+	 * Calls {@link #unbind()} and in addition to that
+	 * also the target is set to null.
+	 * <p>
+	 * This means that the helper won't be usable anymore until {@link #bind(ObservableValue)} and
+	 * {@link #to(ObservableValue)} are called again.
+	 */
+	public void dispose() {
+		unbind();
+		target = null;
+	}
 
-    /**
-     * Asks the {@link BindingManager} to check if this helper's target
-     * is bound.
-     */
-    public boolean isBound() {
-        return BindingManager.instance().isBound(target);
-    }
+	/**
+	 * Asks the {@link BindingManager} to check if this helper's target
+	 * is bound.
+	 */
+	public boolean isBound() {
+		return BindingManager.instance().isBound(target);
+	}
 
-    /**
-     * Checks if the binding should be ignored.
-     */
-    public boolean isIgnoreBinding() {
-        return ignoreBinding;
-    }
+	/**
+	 * Checks if the binding should be ignored.
+	 */
+	public boolean isIgnoreBinding() {
+		return ignoreBinding;
+	}
 
-    /**
-     * Checks if the helper has been disposed before.
-     */
-    @Override
-    public boolean isDispose() {
-        return target == null;
-    }
+	/**
+	 * Checks if the helper has been disposed before.
+	 */
+	@Override
+	public boolean isDispose() {
+		return target == null;
+	}
 }

+ 29 - 29
materialfx/src/main/java/io/github/palexdev/materialfx/bindings/BooleanListBinding.java

@@ -30,37 +30,37 @@ import javafx.collections.ObservableList;
  * when even only one of them is false.
  */
 public class BooleanListBinding extends BooleanBinding {
-    private final ObservableList<BooleanProperty> boundList;
-    private final ListChangeListener<BooleanProperty> changeListener;
-    private BooleanProperty[] observedProperties;
+	private final ObservableList<BooleanProperty> boundList;
+	private final ListChangeListener<BooleanProperty> changeListener;
+	private BooleanProperty[] observedProperties;
 
-    public BooleanListBinding(ObservableList<BooleanProperty> boundList) {
-        this.boundList = boundList;
-        this.changeListener = c -> refreshBinding();
-        this.boundList.addListener(changeListener);
-        refreshBinding();
-    }
+	public BooleanListBinding(ObservableList<BooleanProperty> boundList) {
+		this.boundList = boundList;
+		this.changeListener = c -> refreshBinding();
+		this.boundList.addListener(changeListener);
+		refreshBinding();
+	}
 
-    @Override
-    protected boolean computeValue() {
-        for (BooleanProperty bp : observedProperties) {
-            if (!bp.get()) {
-                return false;
-            }
-        }
-        return true;
-    }
+	@Override
+	protected boolean computeValue() {
+		for (BooleanProperty bp : observedProperties) {
+			if (!bp.get()) {
+				return false;
+			}
+		}
+		return true;
+	}
 
-    @Override
-    public void dispose() {
-        boundList.removeListener(changeListener);
-        super.dispose();
-    }
+	@Override
+	public void dispose() {
+		boundList.removeListener(changeListener);
+		super.dispose();
+	}
 
-    private void refreshBinding() {
-        super.unbind(observedProperties);
-        observedProperties = boundList.toArray(new BooleanProperty[0]);
-        super.bind(observedProperties);
-        this.invalidate();
-    }
+	private void refreshBinding() {
+		super.unbind(observedProperties);
+		observedProperties = boundList.toArray(new BooleanProperty[0]);
+		super.bind(observedProperties);
+		this.invalidate();
+	}
 }

+ 8 - 3
materialfx/src/main/java/io/github/palexdev/materialfx/bindings/base/AbstractBindingHelper.java

@@ -19,6 +19,7 @@ import java.util.function.BiConsumer;
  * disposed before
  * <p> - The method responsible for updating the target (triggered by the sourceListener)
  * <p> - The actions to perform: before/after the target update, before/after the binding, before/after the unbinding
+ *
  * @param <T>
  */
 public abstract class AbstractBindingHelper<T> {
@@ -33,9 +34,13 @@ public abstract class AbstractBindingHelper<T> {
 	// Abstract Properties
 	//================================================================================
 	public abstract AbstractBindingHelper<T> bind(ObservableValue<? extends T> target);
+
 	public abstract AbstractBindingHelper<T> with(BiConsumer<T, T> targetUpdater);
+
 	public abstract void invalidate();
+
 	public abstract void dispose();
+
 	public abstract boolean isDispose();
 
 	//================================================================================
@@ -48,9 +53,9 @@ public abstract class AbstractBindingHelper<T> {
 	 * <p>
 	 * Also calls {@link #beforeUpdateTarget()} and {@link #afterUpdateTarget()}.
 	 *
-	 * @param source    the source property
-	 * @param oldValue  the source's oldValue
-	 * @param newValue  the source's newValue
+	 * @param source   the source property
+	 * @param oldValue the source's oldValue
+	 * @param newValue the source's newValue
 	 */
 	protected void updateTarget(ObservableValue<? extends T> source, T oldValue, T newValue) {
 		beforeUpdateTarget();

+ 23 - 23
materialfx/src/main/java/io/github/palexdev/materialfx/collections/ChangeHelper.java

@@ -6,30 +6,30 @@ import java.util.List;
 class ChangeHelper {
     ChangeHelper() {}
 
-    public static String addRemoveChangeToString(int from, int to, List<?> list, List<?> removed) {
-        StringBuilder sb = new StringBuilder();
-        if (removed.isEmpty()) {
-            sb.append(list.subList(from, to));
-            sb.append(" added at ").append(from);
-        } else {
-            sb.append(removed);
-            if (from == to) {
-                sb.append(" removed at ").append(from);
-            } else {
-                sb.append(" replaced by ");
-                sb.append(list.subList(from, to));
-                sb.append(" at ").append(from);
-            }
-        }
+	public static String addRemoveChangeToString(int from, int to, List<?> list, List<?> removed) {
+		StringBuilder sb = new StringBuilder();
+		if (removed.isEmpty()) {
+			sb.append(list.subList(from, to));
+			sb.append(" added at ").append(from);
+		} else {
+			sb.append(removed);
+			if (from == to) {
+				sb.append(" removed at ").append(from);
+			} else {
+				sb.append(" replaced by ");
+				sb.append(list.subList(from, to));
+				sb.append(" at ").append(from);
+			}
+		}
 
-        return sb.toString();
-    }
+		return sb.toString();
+	}
 
-    public static String permChangeToString(int[] permutation) {
-        return "permutated by " + Arrays.toString(permutation);
-    }
+	public static String permChangeToString(int[] permutation) {
+		return "permutated by " + Arrays.toString(permutation);
+	}
 
-    public static String updateChangeToString(int from, int to) {
-        return "updated at range [" + from + ", " + to + ")";
-    }
+	public static String updateChangeToString(int from, int to) {
+		return "updated at range [" + from + ", " + to + ")";
+	}
 }

+ 48 - 48
materialfx/src/main/java/io/github/palexdev/materialfx/collections/CircularQueue.java

@@ -26,58 +26,58 @@ import java.util.LinkedList;
  * by the new one.
  */
 public class CircularQueue<E> extends LinkedList<E> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private int size;
+	//================================================================================
+	// Properties
+	//================================================================================
+	private int size;
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public CircularQueue(int size) {
-        super();
-        this.size = size;
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public CircularQueue(int size) {
+		super();
+		this.size = size;
+	}
 
-    //================================================================================
-    // Methods
-    //================================================================================
+	//================================================================================
+	// Methods
+	//================================================================================
 
-    /**
-     * Sets the maximum size of the queue and removes exceeding elements
-     * if the specified size is lesser than the number of elements.
-     *
-     * @param size The new desired size
-     * @throws IllegalArgumentException if the desired size is 0
-     */
-    public void setSize(int size) {
-        if (size == 0) {
-            throw new IllegalArgumentException("Size cannot be 0!");
-        }
+	/**
+	 * Sets the maximum size of the queue and removes exceeding elements
+	 * if the specified size is lesser than the number of elements.
+	 *
+	 * @param size The new desired size
+	 * @throws IllegalArgumentException if the desired size is 0
+	 */
+	public void setSize(int size) {
+		if (size == 0) {
+			throw new IllegalArgumentException("Size cannot be 0!");
+		}
 
-        if (size < super.size()) {
-            for (int i = 0; i < (super.size() - size); i++) {
-                super.remove();
-            }
-        }
-        this.size = size;
-    }
+		if (size < super.size()) {
+			for (int i = 0; i < (super.size() - size); i++) {
+				super.remove();
+			}
+		}
+		this.size = size;
+	}
 
-    //================================================================================
-    // Override Methods
-    //================================================================================
+	//================================================================================
+	// Override Methods
+	//================================================================================
 
-    /**
-     * Adds the specified element to the queue and if it is full removes the oldest element
-     * and then adds the new one.
-     * <p></p>
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean add(E e) {
-        if (super.size() == this.size) {
-            super.remove();
-        }
-        return super.add(e);
-    }
+	/**
+	 * Adds the specified element to the queue and if it is full removes the oldest element
+	 * and then adds the new one.
+	 * <p></p>
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean add(E e) {
+		if (super.size() == this.size) {
+			super.remove();
+		}
+		return super.add(e);
+	}
 }

+ 146 - 146
materialfx/src/main/java/io/github/palexdev/materialfx/collections/GenericAddRemoveChange.java

@@ -7,150 +7,150 @@ import java.util.Collections;
 import java.util.List;
 
 abstract class NonIterableChange<E> extends ListChangeListener.Change<E> {
-    private final int from;
-    private final int to;
-    private boolean invalid = true;
-    private static final int[] EMPTY_PERM = new int[0];
-
-    protected NonIterableChange(int from, int to, ObservableList<E> list) {
-        super(list);
-        this.from = from;
-        this.to = to;
-    }
-
-    public int getFrom() {
-        checkState();
-        return from;
-    }
-
-    public int getTo() {
-        checkState();
-        return to;
-    }
-
-    protected int[] getPermutation() {
-        checkState();
-        return EMPTY_PERM;
-    }
-
-    public boolean next() {
-        if (invalid) {
-            invalid = false;
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public void reset() {
-        invalid = true;
-    }
-
-    public void checkState() {
-        if (invalid) {
-            throw new IllegalStateException("Invalid Change state: next() must be called before inspecting the Change.");
-        }
-    }
-
-    public String toString() {
-        boolean oldInvalid = invalid;
-        invalid = false;
-        String ret;
-        if (wasPermutated()) {
-            ret = ChangeHelper.permChangeToString(getPermutation());
-        } else if (wasUpdated()) {
-            ret = ChangeHelper.updateChangeToString(from, to);
-        } else {
-            ret = ChangeHelper.addRemoveChangeToString(from, to, getList(), getRemoved());
-        }
-
-        invalid = oldInvalid;
-        return "{ " + ret + " }";
-    }
-
-    public static class SimpleUpdateChange<E> extends NonIterableChange<E> {
-        public SimpleUpdateChange(int position, ObservableList<E> list) {
-            this(position, position + 1, list);
-        }
-
-        public SimpleUpdateChange(int from, int to, ObservableList<E> list) {
-            super(from, to, list);
-        }
-
-        public List<E> getRemoved() {
-            return Collections.emptyList();
-        }
-
-        public boolean wasUpdated() {
-            return true;
-        }
-    }
-
-    public static class SimplePermutationChange<E> extends NonIterableChange<E> {
-        private final int[] permutation;
-
-        public SimplePermutationChange(int from, int to, int[] permutation, ObservableList<E> list) {
-            super(from, to, list);
-            this.permutation = permutation;
-        }
-
-        public List<E> getRemoved() {
-            checkState();
-            return Collections.emptyList();
-        }
-
-        protected int[] getPermutation() {
-            checkState();
-            return permutation;
-        }
-    }
-
-    public static class SimpleAddChange<E> extends NonIterableChange<E> {
-        public SimpleAddChange(int from, int to, ObservableList<E> list) {
-            super(from, to, list);
-        }
-
-        public boolean wasRemoved() {
-            checkState();
-            return false;
-        }
-
-        public List<E> getRemoved() {
-            checkState();
-            return Collections.emptyList();
-        }
-    }
-
-    public static class SimpleRemovedChange<E> extends NonIterableChange<E> {
-        private final List<E> removed;
-
-        public SimpleRemovedChange(int from, int to, E removed, ObservableList<E> list) {
-            super(from, to, list);
-            this.removed = Collections.singletonList(removed);
-        }
-
-        public boolean wasRemoved() {
-            checkState();
-            return true;
-        }
-
-        public List<E> getRemoved() {
-            checkState();
-            return removed;
-        }
-    }
-
-    public static class GenericAddRemoveChange<E> extends NonIterableChange<E> {
-        private final List<E> removed;
-
-        public GenericAddRemoveChange(int from, int to, List<E> removed, ObservableList<E> list) {
-            super(from, to, list);
-            this.removed = removed;
-        }
-
-        public List<E> getRemoved() {
-            checkState();
-            return removed;
-        }
-    }
+	private final int from;
+	private final int to;
+	private boolean invalid = true;
+	private static final int[] EMPTY_PERM = new int[0];
+
+	protected NonIterableChange(int from, int to, ObservableList<E> list) {
+		super(list);
+		this.from = from;
+		this.to = to;
+	}
+
+	public int getFrom() {
+		checkState();
+		return from;
+	}
+
+	public int getTo() {
+		checkState();
+		return to;
+	}
+
+	protected int[] getPermutation() {
+		checkState();
+		return EMPTY_PERM;
+	}
+
+	public boolean next() {
+		if (invalid) {
+			invalid = false;
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	public void reset() {
+		invalid = true;
+	}
+
+	public void checkState() {
+		if (invalid) {
+			throw new IllegalStateException("Invalid Change state: next() must be called before inspecting the Change.");
+		}
+	}
+
+	public String toString() {
+		boolean oldInvalid = invalid;
+		invalid = false;
+		String ret;
+		if (wasPermutated()) {
+			ret = ChangeHelper.permChangeToString(getPermutation());
+		} else if (wasUpdated()) {
+			ret = ChangeHelper.updateChangeToString(from, to);
+		} else {
+			ret = ChangeHelper.addRemoveChangeToString(from, to, getList(), getRemoved());
+		}
+
+		invalid = oldInvalid;
+		return "{ " + ret + " }";
+	}
+
+	public static class SimpleUpdateChange<E> extends NonIterableChange<E> {
+		public SimpleUpdateChange(int position, ObservableList<E> list) {
+			this(position, position + 1, list);
+		}
+
+		public SimpleUpdateChange(int from, int to, ObservableList<E> list) {
+			super(from, to, list);
+		}
+
+		public List<E> getRemoved() {
+			return Collections.emptyList();
+		}
+
+		public boolean wasUpdated() {
+			return true;
+		}
+	}
+
+	public static class SimplePermutationChange<E> extends NonIterableChange<E> {
+		private final int[] permutation;
+
+		public SimplePermutationChange(int from, int to, int[] permutation, ObservableList<E> list) {
+			super(from, to, list);
+			this.permutation = permutation;
+		}
+
+		public List<E> getRemoved() {
+			checkState();
+			return Collections.emptyList();
+		}
+
+		protected int[] getPermutation() {
+			checkState();
+			return permutation;
+		}
+	}
+
+	public static class SimpleAddChange<E> extends NonIterableChange<E> {
+		public SimpleAddChange(int from, int to, ObservableList<E> list) {
+			super(from, to, list);
+		}
+
+		public boolean wasRemoved() {
+			checkState();
+			return false;
+		}
+
+		public List<E> getRemoved() {
+			checkState();
+			return Collections.emptyList();
+		}
+	}
+
+	public static class SimpleRemovedChange<E> extends NonIterableChange<E> {
+		private final List<E> removed;
+
+		public SimpleRemovedChange(int from, int to, E removed, ObservableList<E> list) {
+			super(from, to, list);
+			this.removed = Collections.singletonList(removed);
+		}
+
+		public boolean wasRemoved() {
+			checkState();
+			return true;
+		}
+
+		public List<E> getRemoved() {
+			checkState();
+			return removed;
+		}
+	}
+
+	public static class GenericAddRemoveChange<E> extends NonIterableChange<E> {
+		private final List<E> removed;
+
+		public GenericAddRemoveChange(int from, int to, List<E> removed, ObservableList<E> list) {
+			super(from, to, list);
+			this.removed = removed;
+		}
+
+		public List<E> getRemoved() {
+			checkState();
+			return removed;
+		}
+	}
 }

+ 274 - 274
materialfx/src/main/java/io/github/palexdev/materialfx/collections/ObservableStack.java

@@ -32,279 +32,279 @@ import java.util.*;
  * @param <E> Any type
  */
 public class ObservableStack<E> extends SimpleListProperty<E> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final LinkedList<E> stack;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public ObservableStack() {
-        this.stack = new LinkedList<>();
-        this.set(FXCollections.observableList(this.stack));
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Places the item at the top of the stack
-     *
-     * @param item the item
-     * @return the item that was just pushed
-     */
-    public E push(E item) {
-        stack.push(item);
-        fireValueChangedEvent(new StackChange(this.get(),
-                ChangeType.PUSH.setChangedObj(Collections.singletonList(item))));
-        return item;
-    }
-
-    /**
-     * @return the item at the top of the stack granted that the stack is not empty
-     * @throws NoSuchElementException if the stack is empty
-     */
-    public E pop() throws NoSuchElementException {
-        E temp = stack.pop();
-        fireValueChangedEvent(new StackChange(this.get(),
-                ChangeType.POP.setChangedObj(Collections.singletonList(temp))));
-        return temp;
-    }
-
-    /**
-     * Pushes the element to the top of the stack
-     *
-     * @param element the element to add
-     * @return Always returns true
-     * @see #push(Object)
-     */
-    @Override
-    public boolean add(E element) {
-        push(element);
-        return true;
-    }
-
-    /**
-     * Removes an element at the given index
-     *
-     * @param i the index to remove from
-     * @return The element that was removed
-     * @throws IllegalArgumentException if i is not 0. The stack can only access the top element
-     * @see #pop()
-     */
-    @Override
-    public E remove(int i) throws IllegalArgumentException {
-        if (0 == i) {
-            return pop();
-        }
-        throw new IllegalArgumentException("Can only modify the top of the stack " + i);
-    }
-
-    /**
-     * Effectively empties the stack given that the stack is not already empty
-     *
-     * @return true if the stack was emptied
-     * @throws NoSuchElementException if the stack is already empty
-     */
-    public boolean removeAll() throws NoSuchElementException {
-        this.get().remove(0, getSize());
-        return true;
-    }
-
-    /**
-     * Adds an element to the given index
-     *
-     * @param i       the index to add the element at
-     * @param element the element to add to the stack
-     * @throws IllegalArgumentException if the index specified is not 0. Only the top of the stack
-     *                                  is accessible
-     * @see #push(Object)
-     */
-    @Override
-    public void add(int i, E element) throws IllegalArgumentException {
-        if (0 == i) {
-            push(element);
-        }
-        throw new IllegalArgumentException("Can only modify the top of the stack " + i);
-    }
-
-    /**
-     * Adds the elements from the collection into the stack in the order they are specified
-     *
-     * @param elements the collection to be added to this stack
-     * @return true
-     * @throws NullPointerException if the collection is null
-     */
-    @Override
-    public boolean addAll(Collection<? extends E> elements) throws NullPointerException {
-        elements.forEach(stack::push);
-        fireValueChangedEvent(new StackChange(this.get(),
-                ChangeType.PUSH.setChangedObj(new ArrayList<>(elements))));
-        return true;
-    }
-
-    /**
-     * Adds the contents of the array into the stack
-     *
-     * @param elements the array of elements to add
-     * @return true
-     * @see #addAll(Collection)
-     */
-    @Override
-    public boolean addAll(E... elements) {
-        return addAll(Arrays.asList(elements));
-    }
-
-    @Override
-    public boolean addAll(int i, Collection<? extends E> elements) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Attempt to remove an arbitrary object from the stack is not permitted
-     *
-     * @param obj The object to remove
-     * @return Nothing
-     * @throws UnsupportedOperationException Removing an arbitrary object is not permitted Use
-     *                                       {@link #pop()}
-     */
-    @Override
-    public boolean remove(Object obj) throws UnsupportedOperationException {
-        throw new UnsupportedOperationException("Operation not allowed, use pop");
-    }
-
-    /**
-     * Attempt to remove a range of objects from the stack, this is also not permitted
-     *
-     * @param from Start removing from here
-     * @param to   To here
-     * @throws UnsupportedOperationException {@link #remove(Object)}
-     */
-    @Override
-    public void remove(int from, int to) throws UnsupportedOperationException {
-        throw new UnsupportedOperationException("Operation not allowed, use pop");
-    }
-
-    @Override
-    public boolean removeAll(E... elements) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean removeAll(Collection<?> objects) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Used to determine what change occurred in the stack
-     */
-    private enum ChangeType {
-        PUSH, POP;
-
-        /**
-         * The object that was changed
-         */
-        private List changedObj;
-
-        /**
-         * The changed object(s) are packaged as a list
-         *
-         * @return The list of changed objects
-         */
-        public List getChangedObj() {
-            return changedObj;
-        }
-
-        /**
-         * Method to accept the changed object
-         *
-         * @param obj the list of objects that were changed in the stack
-         * @return this enum
-         */
-        public ChangeType setChangedObj(List obj) {
-            this.changedObj = obj;
-            return this;
-        }
-    }
-
-    private final class StackChange extends ListChangeListener.Change<E> {
-
-        private final ChangeType type;
-        private boolean onChange;
-
-        /**
-         * Constructs a new change done to a list.
-         *
-         * @param list that was changed
-         */
-        public StackChange(ObservableList<E> list, ChangeType type) {
-            super(list);
-            this.type = type;
-            onChange = false;
-        }
-
-        @Override
-        public boolean wasAdded() {
-            return type == ChangeType.PUSH;
-        }
-
-        @Override
-        public boolean wasRemoved() {
-            return type == ChangeType.POP;
-        }
-
-        @Override
-        public boolean next() {
-            if (onChange) {
-                return false;
-            }
-            onChange = true;
-            return true;
-        }
-
-        @Override
-        public void reset() {
-            onChange = false;
-        }
-
-        /**
-         * Because this is a stack, all push and pop happen to the first item in the stack
-         *
-         * @return index of the first item
-         */
-        @Override
-        public int getFrom() {
-            if (!onChange) {
-                throw new IllegalStateException(
-                        "Invalid Change state: next() must be called before inspecting the Change.");
-            }
-            return 0;
-        }
-
-        /**
-         * @return the size of the list returned which indicates the end of the change
-         */
-        @Override
-        public int getTo() {
-            if (!onChange) {
-                throw new IllegalStateException(
-                        "Invalid Change state: next() must be called before inspecting the Change.");
-            }
-            return type.getChangedObj().size();
-        }
-
-        @Override
-        public List<E> getRemoved() {
-            return wasRemoved() ? type.getChangedObj() :
-                    Collections.emptyList();
-        }
-
-        @Override
-        protected int[] getPermutation() {
-            return new int[0];
-        }
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final LinkedList<E> stack;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public ObservableStack() {
+		this.stack = new LinkedList<>();
+		this.set(FXCollections.observableList(this.stack));
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Places the item at the top of the stack
+	 *
+	 * @param item the item
+	 * @return the item that was just pushed
+	 */
+	public E push(E item) {
+		stack.push(item);
+		fireValueChangedEvent(new StackChange(this.get(),
+				ChangeType.PUSH.setChangedObj(Collections.singletonList(item))));
+		return item;
+	}
+
+	/**
+	 * @return the item at the top of the stack granted that the stack is not empty
+	 * @throws NoSuchElementException if the stack is empty
+	 */
+	public E pop() throws NoSuchElementException {
+		E temp = stack.pop();
+		fireValueChangedEvent(new StackChange(this.get(),
+				ChangeType.POP.setChangedObj(Collections.singletonList(temp))));
+		return temp;
+	}
+
+	/**
+	 * Pushes the element to the top of the stack
+	 *
+	 * @param element the element to add
+	 * @return Always returns true
+	 * @see #push(Object)
+	 */
+	@Override
+	public boolean add(E element) {
+		push(element);
+		return true;
+	}
+
+	/**
+	 * Removes an element at the given index
+	 *
+	 * @param i the index to remove from
+	 * @return The element that was removed
+	 * @throws IllegalArgumentException if i is not 0. The stack can only access the top element
+	 * @see #pop()
+	 */
+	@Override
+	public E remove(int i) throws IllegalArgumentException {
+		if (0 == i) {
+			return pop();
+		}
+		throw new IllegalArgumentException("Can only modify the top of the stack " + i);
+	}
+
+	/**
+	 * Effectively empties the stack given that the stack is not already empty
+	 *
+	 * @return true if the stack was emptied
+	 * @throws NoSuchElementException if the stack is already empty
+	 */
+	public boolean removeAll() throws NoSuchElementException {
+		this.get().remove(0, getSize());
+		return true;
+	}
+
+	/**
+	 * Adds an element to the given index
+	 *
+	 * @param i       the index to add the element at
+	 * @param element the element to add to the stack
+	 * @throws IllegalArgumentException if the index specified is not 0. Only the top of the stack
+	 *                                  is accessible
+	 * @see #push(Object)
+	 */
+	@Override
+	public void add(int i, E element) throws IllegalArgumentException {
+		if (0 == i) {
+			push(element);
+		}
+		throw new IllegalArgumentException("Can only modify the top of the stack " + i);
+	}
+
+	/**
+	 * Adds the elements from the collection into the stack in the order they are specified
+	 *
+	 * @param elements the collection to be added to this stack
+	 * @return true
+	 * @throws NullPointerException if the collection is null
+	 */
+	@Override
+	public boolean addAll(Collection<? extends E> elements) throws NullPointerException {
+		elements.forEach(stack::push);
+		fireValueChangedEvent(new StackChange(this.get(),
+				ChangeType.PUSH.setChangedObj(new ArrayList<>(elements))));
+		return true;
+	}
+
+	/**
+	 * Adds the contents of the array into the stack
+	 *
+	 * @param elements the array of elements to add
+	 * @return true
+	 * @see #addAll(Collection)
+	 */
+	@Override
+	public boolean addAll(E... elements) {
+		return addAll(Arrays.asList(elements));
+	}
+
+	@Override
+	public boolean addAll(int i, Collection<? extends E> elements) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Attempt to remove an arbitrary object from the stack is not permitted
+	 *
+	 * @param obj The object to remove
+	 * @return Nothing
+	 * @throws UnsupportedOperationException Removing an arbitrary object is not permitted Use
+	 *                                       {@link #pop()}
+	 */
+	@Override
+	public boolean remove(Object obj) throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Operation not allowed, use pop");
+	}
+
+	/**
+	 * Attempt to remove a range of objects from the stack, this is also not permitted
+	 *
+	 * @param from Start removing from here
+	 * @param to   To here
+	 * @throws UnsupportedOperationException {@link #remove(Object)}
+	 */
+	@Override
+	public void remove(int from, int to) throws UnsupportedOperationException {
+		throw new UnsupportedOperationException("Operation not allowed, use pop");
+	}
+
+	@Override
+	public boolean removeAll(E... elements) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public boolean removeAll(Collection<?> objects) {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Used to determine what change occurred in the stack
+	 */
+	private enum ChangeType {
+		PUSH, POP;
+
+		/**
+		 * The object that was changed
+		 */
+		private List changedObj;
+
+		/**
+		 * The changed object(s) are packaged as a list
+		 *
+		 * @return The list of changed objects
+		 */
+		public List getChangedObj() {
+			return changedObj;
+		}
+
+		/**
+		 * Method to accept the changed object
+		 *
+		 * @param obj the list of objects that were changed in the stack
+		 * @return this enum
+		 */
+		public ChangeType setChangedObj(List obj) {
+			this.changedObj = obj;
+			return this;
+		}
+	}
+
+	private final class StackChange extends ListChangeListener.Change<E> {
+
+		private final ChangeType type;
+		private boolean onChange;
+
+		/**
+		 * Constructs a new change done to a list.
+		 *
+		 * @param list that was changed
+		 */
+		public StackChange(ObservableList<E> list, ChangeType type) {
+			super(list);
+			this.type = type;
+			onChange = false;
+		}
+
+		@Override
+		public boolean wasAdded() {
+			return type == ChangeType.PUSH;
+		}
+
+		@Override
+		public boolean wasRemoved() {
+			return type == ChangeType.POP;
+		}
+
+		@Override
+		public boolean next() {
+			if (onChange) {
+				return false;
+			}
+			onChange = true;
+			return true;
+		}
+
+		@Override
+		public void reset() {
+			onChange = false;
+		}
+
+		/**
+		 * Because this is a stack, all push and pop happen to the first item in the stack
+		 *
+		 * @return index of the first item
+		 */
+		@Override
+		public int getFrom() {
+			if (!onChange) {
+				throw new IllegalStateException(
+						"Invalid Change state: next() must be called before inspecting the Change.");
+			}
+			return 0;
+		}
+
+		/**
+		 * @return the size of the list returned which indicates the end of the change
+		 */
+		@Override
+		public int getTo() {
+			if (!onChange) {
+				throw new IllegalStateException(
+						"Invalid Change state: next() must be called before inspecting the Change.");
+			}
+			return type.getChangedObj().size();
+		}
+
+		@Override
+		public List<E> getRemoved() {
+			return wasRemoved() ? type.getChangedObj() :
+					Collections.emptyList();
+		}
+
+		@Override
+		protected int[] getPermutation() {
+			return new int[0];
+		}
+	}
 }
 

+ 184 - 184
materialfx/src/main/java/io/github/palexdev/materialfx/collections/TransformableList.java

@@ -48,7 +48,7 @@ import java.util.stream.IntStream;
  *     // You'll notice that sometimes sourceToView will return a negative index because the item is not in the transformed list (after a filter operation)
  * }
  * </pre>
- *
+ * <p>
  * Check {@link #computeIndexes()} documentation to see how indexes are calculated.
  * <p></p>
  * <b>IMPORTANT:</b> If using a reversed comparator please use {@link #setComparator(Comparator, boolean)} with 'true' as argument,
@@ -58,213 +58,213 @@ import java.util.stream.IntStream;
  * @param <T> the items' type
  */
 public class TransformableList<T> extends TransformationList<T, T> {
-    //================================================================================
-    // Constructors
-    //================================================================================
-    private final List<Integer> indexes = new ArrayList<>();
-    private boolean reversed = false;
+	//================================================================================
+	// Constructors
+	//================================================================================
+	private final List<Integer> indexes = new ArrayList<>();
+	private boolean reversed = false;
 
-    private final PredicateProperty<T> predicate = new PredicateProperty<>() {
-        @Override
-        protected void invalidated() {
-            update();
-        }
-    };
+	private final PredicateProperty<T> predicate = new PredicateProperty<>() {
+		@Override
+		protected void invalidated() {
+			update();
+		}
+	};
 
-    private final ComparatorProperty<T> comparator = new ComparatorProperty<>() {
-        @Override
-        protected void invalidated() {
-            update();
-        }
-    };
+	private final ComparatorProperty<T> comparator = new ComparatorProperty<>() {
+		@Override
+		protected void invalidated() {
+			update();
+		}
+	};
 
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public TransformableList(ObservableList<? extends T> source) {
-        this(source, null);
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public TransformableList(ObservableList<? extends T> source) {
+		this(source, null);
+	}
 
-    public TransformableList(ObservableList<? extends T> source, Predicate<T> predicate) {
-        this(source, predicate, null);
-    }
+	public TransformableList(ObservableList<? extends T> source, Predicate<T> predicate) {
+		this(source, predicate, null);
+	}
 
-    public TransformableList(ObservableList<? extends T> source, Predicate<T> predicate, Comparator<T> comparator) {
-        super(source);
-        setPredicate(predicate);
-        setComparator(comparator);
-        update();
-    }
+	public TransformableList(ObservableList<? extends T> source, Predicate<T> predicate, Comparator<T> comparator) {
+		super(source);
+		setPredicate(predicate);
+		setComparator(comparator);
+		update();
+	}
 
-    //================================================================================
-    // Methods
-    //================================================================================
+	//================================================================================
+	// Methods
+	//================================================================================
 
-    /**
-     * Calls {@link #getSourceIndex(int)}, just with a different name to be more clear.
-     * <p></p>
-     * Maps an index of the transformed list, to the index of the source list.
-     */
-    public int viewToSource(int index) {
-        return getSourceIndex(index);
-    }
+	/**
+	 * Calls {@link #getSourceIndex(int)}, just with a different name to be more clear.
+	 * <p></p>
+	 * Maps an index of the transformed list, to the index of the source list.
+	 */
+	public int viewToSource(int index) {
+		return getSourceIndex(index);
+	}
 
-    /**
-     * Calls {@link #getViewIndex(int)}, just with a different name to be more clear.
-     * <p></p>
-     * Maps an index of the source list, to the index of the transformed list.
-     */
-    public int sourceToView(int index) {
-        return getViewIndex(index);
-    }
+	/**
+	 * Calls {@link #getViewIndex(int)}, just with a different name to be more clear.
+	 * <p></p>
+	 * Maps an index of the source list, to the index of the transformed list.
+	 */
+	public int sourceToView(int index) {
+		return getViewIndex(index);
+	}
 
-    /**
-     * Responsible for updating the transformed indexes when the
-     * predicate or the comparator change.
-     */
-    private void update() {
-        indexes.clear();
-        indexes.addAll(computeIndexes());
-        if (this.hasListeners()) {
-            this.fireChange(new GenericAddRemoveChange<>(0, size(), new ArrayList<>(this), this));
-        }
-    }
+	/**
+	 * Responsible for updating the transformed indexes when the
+	 * predicate or the comparator change.
+	 */
+	private void update() {
+		indexes.clear();
+		indexes.addAll(computeIndexes());
+		if (this.hasListeners()) {
+			this.fireChange(new GenericAddRemoveChange<>(0, size(), new ArrayList<>(this), this));
+		}
+	}
 
-    /**
-     * Core method of TransformableLists. This is responsible for computing
-     * the transformed indexes by creating a {@link SortedMap} and mapping every index from 0 to source size
-     * to its item. Before mapping, items are filtered with the given predicate, {@link #predicateProperty()}.
-     * Before returning, the map's entry set is sorted by its values with the given comparator, {@link #comparatorProperty()}.
-     * Finally, returns the map's key set, this set contains the transformed indexes, filtered and sorted.
-     */
-    private Collection<Integer> computeIndexes() {
-        Predicate<? super T> filter = this.getPredicate();
-        Comparator<? super T> sorter = this.getComparator();
-        SortedMap<Integer, T> sourceMap;
-        if (filter != null) {
-            sourceMap = IntStream.range(0, getSource().size())
-                    .filter((index) -> filter.test(getSource().get(index)))
-                    .collect(TreeMap::new, (map, index) -> map.put(index, getSource().get(index)), TreeMap::putAll);
-        } else {
-            sourceMap = IntStream.range(0, getSource().size())
-                    .collect(TreeMap::new, (map, index) -> map.put(index, getSource().get(index)), TreeMap::putAll);
-        }
+	/**
+	 * Core method of TransformableLists. This is responsible for computing
+	 * the transformed indexes by creating a {@link SortedMap} and mapping every index from 0 to source size
+	 * to its item. Before mapping, items are filtered with the given predicate, {@link #predicateProperty()}.
+	 * Before returning, the map's entry set is sorted by its values with the given comparator, {@link #comparatorProperty()}.
+	 * Finally, returns the map's key set, this set contains the transformed indexes, filtered and sorted.
+	 */
+	private Collection<Integer> computeIndexes() {
+		Predicate<? super T> filter = this.getPredicate();
+		Comparator<? super T> sorter = this.getComparator();
+		SortedMap<Integer, T> sourceMap;
+		if (filter != null) {
+			sourceMap = IntStream.range(0, getSource().size())
+					.filter((index) -> filter.test(getSource().get(index)))
+					.collect(TreeMap::new, (map, index) -> map.put(index, getSource().get(index)), TreeMap::putAll);
+		} else {
+			sourceMap = IntStream.range(0, getSource().size())
+					.collect(TreeMap::new, (map, index) -> map.put(index, getSource().get(index)), TreeMap::putAll);
+		}
 
-        return sorter != null ? sourceMap.entrySet().stream()
-                .sorted((o1, o2) -> sorter.compare(o1.getValue(), o2.getValue()))
-                .map(Map.Entry::getKey)
-                .collect(Collectors.toList()) : sourceMap.keySet();
-    }
+		return sorter != null ? sourceMap.entrySet().stream()
+				.sorted((o1, o2) -> sorter.compare(o1.getValue(), o2.getValue()))
+				.map(Map.Entry::getKey)
+				.collect(Collectors.toList()) : sourceMap.keySet();
+	}
 
-    public Predicate<? super T> getPredicate() {
-        return this.predicate.get();
-    }
+	public Predicate<? super T> getPredicate() {
+		return this.predicate.get();
+	}
 
-    /**
-     * Specifies the predicate used to filter the source list.
-     */
-    public PredicateProperty<T> predicateProperty() {
-        return this.predicate;
-    }
+	/**
+	 * Specifies the predicate used to filter the source list.
+	 */
+	public PredicateProperty<T> predicateProperty() {
+		return this.predicate;
+	}
 
-    public void setPredicate(Predicate<T> predicate) {
-        this.predicate.set(predicate);
-    }
+	public void setPredicate(Predicate<T> predicate) {
+		this.predicate.set(predicate);
+	}
 
-    public Comparator<T> getComparator() {
-        return this.comparator.get();
-    }
+	public Comparator<T> getComparator() {
+		return this.comparator.get();
+	}
 
-    /**
-     * Specifies the comparator used to sort the source list.
-     *
-     * @see #setComparator(Comparator, boolean)
-     */
-    public ComparatorProperty<T> comparatorProperty() {
-        return this.comparator;
-    }
+	/**
+	 * Specifies the comparator used to sort the source list.
+	 *
+	 * @see #setComparator(Comparator, boolean)
+	 */
+	public ComparatorProperty<T> comparatorProperty() {
+		return this.comparator;
+	}
 
-    public void setComparator(Comparator<T> comparator) {
-        this.reversed = false;
-        this.comparator.set(comparator);
-    }
+	public void setComparator(Comparator<T> comparator) {
+		this.reversed = false;
+		this.comparator.set(comparator);
+	}
 
-    /**
-     * This method is NECESSARY if using a reversed comparator,
-     * a special flag is set to true and {@link #sourceToView(int)} behaves accordingly.
-     */
-    public void setComparator(Comparator<T> comparator, boolean reversed) {
-        this.reversed = reversed;
-        this.comparator.set(comparator);
-    }
+	/**
+	 * This method is NECESSARY if using a reversed comparator,
+	 * a special flag is set to true and {@link #sourceToView(int)} behaves accordingly.
+	 */
+	public void setComparator(Comparator<T> comparator, boolean reversed) {
+		this.reversed = reversed;
+		this.comparator.set(comparator);
+	}
 
-    /**
-     * Specifies if a reversed comparator is being used.
-     */
-    public boolean isReversed() {
-        return reversed;
-    }
+	/**
+	 * Specifies if a reversed comparator is being used.
+	 */
+	public boolean isReversed() {
+		return reversed;
+	}
 
-    /**
-     * Communicates to the transformed list, specifically to {@link #getViewIndex(int)},
-     * if the list is sorted in reversed order.
-     */
-    public void setReversed(boolean reversed) {
-        this.reversed = reversed;
-    }
+	/**
+	 * Communicates to the transformed list, specifically to {@link #getViewIndex(int)},
+	 * if the list is sorted in reversed order.
+	 */
+	public void setReversed(boolean reversed) {
+		this.reversed = reversed;
+	}
 
-    //================================================================================
-    // Overridden Methods
-    //================================================================================
+	//================================================================================
+	// Overridden Methods
+	//================================================================================
 
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Calls {@link #update()}.
-     */
-    @Override
-    protected void sourceChanged(ListChangeListener.Change<? extends T> c) {
-        beginChange();
-        update();
-        endChange();
-    }
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Calls {@link #update()}.
+	 */
+	@Override
+	protected void sourceChanged(ListChangeListener.Change<? extends T> c) {
+		beginChange();
+		update();
+		endChange();
+	}
 
-    /**
-     * @return the number of items in the transformable list
-     */
-    @Override
-    public int size() {
-        return indexes.size();
-    }
+	/**
+	 * @return the number of items in the transformable list
+	 */
+	@Override
+	public int size() {
+		return indexes.size();
+	}
 
-    /**
-     * Retrieves and return the item at the given index in the transformable list.
-     * This means transformations due to {@link #predicateProperty()} or {@link #comparatorProperty()}
-     * are taken into account.
-     */
-    @Override
-    public T get(int index) {
-        if (index > size()) {
-            throw new IndexOutOfBoundsException(index);
-        } else {
-            return getSource().get(indexes.get(index));
-        }
-    }
+	/**
+	 * Retrieves and return the item at the given index in the transformable list.
+	 * This means transformations due to {@link #predicateProperty()} or {@link #comparatorProperty()}
+	 * are taken into account.
+	 */
+	@Override
+	public T get(int index) {
+		if (index > size()) {
+			throw new IndexOutOfBoundsException(index);
+		} else {
+			return getSource().get(indexes.get(index));
+		}
+	}
 
-    @Override
-    public int getSourceIndex(int index) {
-        if (index > size()) {
-            throw new IndexOutOfBoundsException(index);
-        } else {
-            return indexes.get(index);
-        }
-    }
+	@Override
+	public int getSourceIndex(int index) {
+		if (index > size()) {
+			throw new IndexOutOfBoundsException(index);
+		} else {
+			return indexes.get(index);
+		}
+	}
 
-    @Override
-    public int getViewIndex(int index) {
-        int viewIndex = reversed ?
-                Collections.binarySearch(indexes, index, Collections.reverseOrder()) :
-                Collections.binarySearch(indexes, index);
-        return viewIndex < 0 ? -1 : viewIndex;
-    }
+	@Override
+	public int getViewIndex(int index) {
+		int viewIndex = reversed ?
+				Collections.binarySearch(indexes, index, Collections.reverseOrder()) :
+				Collections.binarySearch(indexes, index);
+		return viewIndex < 0 ? -1 : viewIndex;
+	}
 }

+ 296 - 297
materialfx/src/main/java/io/github/palexdev/materialfx/collections/TransformableListWrapper.java

@@ -21,304 +21,303 @@ import java.util.function.Predicate;
  * <p>
  * This way you can benefit of the futures of the new {@link TransformableList} (sorting and filtering)
  * while also being able to directly modify the source list.
- * @param <T>
  */
 @SuppressWarnings({"unchecked", "NullableProblems"})
 public class TransformableListWrapper<T> extends AbstractList<T> implements ObservableList<T> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final ObservableList<T> source;
-    private final TransformableList<T> transformableList;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public TransformableListWrapper(ObservableList<T> source) {
-        this.source = source;
-        this.transformableList = new TransformableList<>(source);
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Added to the {@link TransformableList}.
-     */
-    @Override
-    public void addListener(ListChangeListener<? super T> listener) {
-        transformableList.addListener(listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Removed from the {@link TransformableList}.
-     */
-    @Override
-    public void removeListener(ListChangeListener<? super T> listener) {
-        transformableList.removeListener(listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Added to the source list.
-     */
-    @Override
-    public boolean add(T t) {
-        return source.add(t);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Set on the source list.
-     */
-    @Override
-    public T set(int index, T element) {
-        return source.set(index, element);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Added to the source list.
-     */
-    @Override
-    public void add(int index, T element) {
-        source.add(index, element);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Removed from the source list.
-     */
-    @Override
-    public T remove(int index) {
-        return source.remove(index);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Retrieved from the {@link TransformableList}.
-     */
-    @Override
-    public int indexOf(Object o) {
-        return transformableList.indexOf(o);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Retrieved from the {@link TransformableList}.
-     */
-    @Override
-    public int lastIndexOf(Object o) {
-        return transformableList.lastIndexOf(o);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * The source list is cleared.
-     */
-    @Override
-    public void clear() {
-        source.clear();
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Added to the source list.
-     */
-    @Override
-    public boolean addAll(int index, Collection<? extends T> c) {
-        return source.addAll(index, c);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Added to the source list.
-     */
-    @Override
-    public boolean addAll(T... elements) {
-        return source.addAll(elements);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Set on the source list.
-     */
-    @Override
-    public boolean setAll(T... elements) {
-        return source.setAll(elements);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Set on the source list.
-     */
-    @Override
-    public boolean setAll(Collection<? extends T> col) {
-        return source.setAll(col);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Removed from the source list.
-     */
-    @Override
-    public boolean removeAll(T... elements) {
-        return source.removeAll(elements);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Retained on the source list.
-     */
-    @Override
-    public boolean retainAll(T... elements) {
-        return source.retainAll(elements);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Removed from the source list.
-     */
-    @Override
-    public void remove(int from, int to) {
-        source.remove(from, to);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Added to the {@link TransformableList}.
-     */
-    @Override
-    public void addListener(InvalidationListener listener) {
-        transformableList.addListener(listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Removed from the {@link TransformableList}.
-     */
-    @Override
-    public void removeListener(InvalidationListener listener) {
-        transformableList.removeListener(listener);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Retrieved from the {@link TransformableList}.
-     */
-    @Override
-    public T get(int index) {
-        return transformableList.get(index);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p></p>
-     * Size of the {@link TransformableList}.
-     */
-    @Override
-    public int size() {
-        return transformableList.size();
-    }
-
-    /**
-     * @return the source observable list
-     */
-    public ObservableList<? extends T> getSource() {
-        return transformableList.getSource();
-    }
-
-    /**
-     * Delegate for {@link TransformableList#viewToSource(int)}.
-     */
-    public int viewToSource(int index) {
-        return transformableList.viewToSource(index);
-    }
-
-    /**
-     * Delegate for {@link TransformableList#sourceToView(int)}.
-     */
-    public int sourceToView(int index) {
-        return transformableList.sourceToView(index);
-    }
-
-    public Predicate<? super T> getPredicate() {
-        return transformableList.getPredicate();
-    }
-
-    /**
-     * Delegate for {@link TransformableList#predicateProperty()}.
-     */
-    public PredicateProperty<T> predicateProperty() {
-        return transformableList.predicateProperty();
-    }
-
-    public void setPredicate(Predicate<T> predicate) {
-        transformableList.setPredicate(predicate);
-    }
-
-    public Comparator<T> getComparator() {
-        return transformableList.getComparator();
-    }
-
-    /**
-     * Delegate for {@link TransformableList#comparatorProperty()}.
-     */
-    public ComparatorProperty<T> comparatorProperty() {
-        return transformableList.comparatorProperty();
-    }
-
-    public void setComparator(Comparator<T> comparator) {
-        transformableList.setComparator(comparator);
-    }
-
-    /**
-     * Delegate for {@link TransformableList#setComparator(Comparator, boolean)}.
-     */
-    public void setComparator(Comparator<T> sorter, boolean reversed) {
-        transformableList.setComparator(sorter, reversed);
-    }
-
-    /**
-     * Delegate for {@link TransformableList#isReversed()}.
-     */
-    public boolean isReversed() {
-        return transformableList.isReversed();
-    }
-
-    /**
-     * Delegate for {@link TransformableList#setReversed(boolean)}.
-     */
-    public void setReversed(boolean reversed) {
-        transformableList.setReversed(reversed);
-    }
-
-    /**
-     * @return the wrapped {@link TransformableList}
-     */
-    public TransformableList<T> getTransformableList() {
-        return transformableList;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final ObservableList<T> source;
+	private final TransformableList<T> transformableList;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public TransformableListWrapper(ObservableList<T> source) {
+		this.source = source;
+		this.transformableList = new TransformableList<>(source);
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Added to the {@link TransformableList}.
+	 */
+	@Override
+	public void addListener(ListChangeListener<? super T> listener) {
+		transformableList.addListener(listener);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Removed from the {@link TransformableList}.
+	 */
+	@Override
+	public void removeListener(ListChangeListener<? super T> listener) {
+		transformableList.removeListener(listener);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Added to the source list.
+	 */
+	@Override
+	public boolean add(T t) {
+		return source.add(t);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Set on the source list.
+	 */
+	@Override
+	public T set(int index, T element) {
+		return source.set(index, element);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Added to the source list.
+	 */
+	@Override
+	public void add(int index, T element) {
+		source.add(index, element);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Removed from the source list.
+	 */
+	@Override
+	public T remove(int index) {
+		return source.remove(index);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Retrieved from the {@link TransformableList}.
+	 */
+	@Override
+	public int indexOf(Object o) {
+		return transformableList.indexOf(o);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Retrieved from the {@link TransformableList}.
+	 */
+	@Override
+	public int lastIndexOf(Object o) {
+		return transformableList.lastIndexOf(o);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * The source list is cleared.
+	 */
+	@Override
+	public void clear() {
+		source.clear();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Added to the source list.
+	 */
+	@Override
+	public boolean addAll(int index, Collection<? extends T> c) {
+		return source.addAll(index, c);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Added to the source list.
+	 */
+	@Override
+	public boolean addAll(T... elements) {
+		return source.addAll(elements);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Set on the source list.
+	 */
+	@Override
+	public boolean setAll(T... elements) {
+		return source.setAll(elements);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Set on the source list.
+	 */
+	@Override
+	public boolean setAll(Collection<? extends T> col) {
+		return source.setAll(col);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Removed from the source list.
+	 */
+	@Override
+	public boolean removeAll(T... elements) {
+		return source.removeAll(elements);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Retained on the source list.
+	 */
+	@Override
+	public boolean retainAll(T... elements) {
+		return source.retainAll(elements);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Removed from the source list.
+	 */
+	@Override
+	public void remove(int from, int to) {
+		source.remove(from, to);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Added to the {@link TransformableList}.
+	 */
+	@Override
+	public void addListener(InvalidationListener listener) {
+		transformableList.addListener(listener);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Removed from the {@link TransformableList}.
+	 */
+	@Override
+	public void removeListener(InvalidationListener listener) {
+		transformableList.removeListener(listener);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Retrieved from the {@link TransformableList}.
+	 */
+	@Override
+	public T get(int index) {
+		return transformableList.get(index);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p></p>
+	 * Size of the {@link TransformableList}.
+	 */
+	@Override
+	public int size() {
+		return transformableList.size();
+	}
+
+	/**
+	 * @return the source observable list
+	 */
+	public ObservableList<? extends T> getSource() {
+		return transformableList.getSource();
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#viewToSource(int)}.
+	 */
+	public int viewToSource(int index) {
+		return transformableList.viewToSource(index);
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#sourceToView(int)}.
+	 */
+	public int sourceToView(int index) {
+		return transformableList.sourceToView(index);
+	}
+
+	public Predicate<? super T> getPredicate() {
+		return transformableList.getPredicate();
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#predicateProperty()}.
+	 */
+	public PredicateProperty<T> predicateProperty() {
+		return transformableList.predicateProperty();
+	}
+
+	public void setPredicate(Predicate<T> predicate) {
+		transformableList.setPredicate(predicate);
+	}
+
+	public Comparator<T> getComparator() {
+		return transformableList.getComparator();
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#comparatorProperty()}.
+	 */
+	public ComparatorProperty<T> comparatorProperty() {
+		return transformableList.comparatorProperty();
+	}
+
+	public void setComparator(Comparator<T> comparator) {
+		transformableList.setComparator(comparator);
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#setComparator(Comparator, boolean)}.
+	 */
+	public void setComparator(Comparator<T> sorter, boolean reversed) {
+		transformableList.setComparator(sorter, reversed);
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#isReversed()}.
+	 */
+	public boolean isReversed() {
+		return transformableList.isReversed();
+	}
+
+	/**
+	 * Delegate for {@link TransformableList#setReversed(boolean)}.
+	 */
+	public void setReversed(boolean reversed) {
+		transformableList.setReversed(reversed);
+	}
+
+	/**
+	 * @return the wrapped {@link TransformableList}
+	 */
+	public TransformableList<T> getTransformableList() {
+		return transformableList;
+	}
 }

+ 31 - 31
materialfx/src/main/java/io/github/palexdev/materialfx/controls/BoundLabel.java

@@ -11,37 +11,37 @@ import javafx.scene.control.Labeled;
  */
 public class BoundLabel extends Label {
 
-    public BoundLabel(Labeled labeled) {
-        super();
+	public BoundLabel(Labeled labeled) {
+		super();
 
-        // Init
-        setText(labeled.getText());
-        setFont(labeled.getFont());
-        setTextFill(labeled.getTextFill());
-        setWrapText(labeled.isWrapText());
-        setTextAlignment(labeled.getTextAlignment());
-        setTextOverrun(labeled.getTextOverrun());
-        setEllipsisString(labeled.getEllipsisString());
-        setUnderline(labeled.isUnderline());
-        setLineSpacing(labeled.getLineSpacing());
-        setGraphicTextGap(labeled.getGraphicTextGap());
-        setContentDisplay(labeled.getContentDisplay());
-        setGraphic(labeled.getGraphic());
-        setAlignment(labeled.getAlignment());
+		// Init
+		setText(labeled.getText());
+		setFont(labeled.getFont());
+		setTextFill(labeled.getTextFill());
+		setWrapText(labeled.isWrapText());
+		setTextAlignment(labeled.getTextAlignment());
+		setTextOverrun(labeled.getTextOverrun());
+		setEllipsisString(labeled.getEllipsisString());
+		setUnderline(labeled.isUnderline());
+		setLineSpacing(labeled.getLineSpacing());
+		setGraphicTextGap(labeled.getGraphicTextGap());
+		setContentDisplay(labeled.getContentDisplay());
+		setGraphic(labeled.getGraphic());
+		setAlignment(labeled.getAlignment());
 
-        // Bindings
-        textProperty().bind(labeled.textProperty());
-        fontProperty().bind(labeled.fontProperty());
-        textFillProperty().bind(labeled.textFillProperty());
-        wrapTextProperty().bind(labeled.wrapTextProperty());
-        textAlignmentProperty().bind(labeled.textAlignmentProperty());
-        textOverrunProperty().bind(labeled.textOverrunProperty());
-        ellipsisStringProperty().bind(labeled.ellipsisStringProperty());
-        underlineProperty().bind(labeled.underlineProperty());
-        lineSpacingProperty().bind(labeled.lineSpacingProperty());
-        graphicTextGapProperty().bind(labeled.graphicTextGapProperty());
-        contentDisplayProperty().bind(labeled.contentDisplayProperty());
-        graphicProperty().bind(labeled.graphicProperty());
-        alignmentProperty().bind(labeled.alignmentProperty());
-    }
+		// Bindings
+		textProperty().bind(labeled.textProperty());
+		fontProperty().bind(labeled.fontProperty());
+		textFillProperty().bind(labeled.textFillProperty());
+		wrapTextProperty().bind(labeled.wrapTextProperty());
+		textAlignmentProperty().bind(labeled.textAlignmentProperty());
+		textOverrunProperty().bind(labeled.textOverrunProperty());
+		ellipsisStringProperty().bind(labeled.ellipsisStringProperty());
+		underlineProperty().bind(labeled.underlineProperty());
+		lineSpacingProperty().bind(labeled.lineSpacingProperty());
+		graphicTextGapProperty().bind(labeled.graphicTextGapProperty());
+		contentDisplayProperty().bind(labeled.contentDisplayProperty());
+		graphicProperty().bind(labeled.graphicProperty());
+		alignmentProperty().bind(labeled.alignmentProperty());
+	}
 }

+ 317 - 317
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXButton.java

@@ -43,321 +43,321 @@ import java.util.List;
  * includes a {@code RippleGenerator} to generate ripple effects on click.
  */
 public class MFXButton extends Button {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private static final StyleablePropertyFactory<MFXButton> FACTORY = new StyleablePropertyFactory<>(Button.getClassCssMetaData());
-    private final String STYLE_CLASS = "mfx-button";
-    private final String STYLESHEET = MFXResourcesLoader.load("css/MFXButton.css");
-    private final MFXCircleRippleGenerator rippleGenerator = new MFXCircleRippleGenerator(this);
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXButton() {
-        setText("Button");
-        initialize();
-    }
-
-    public MFXButton(String text) {
-        super(text);
-        initialize();
-    }
-
-    public MFXButton(String text, double prefWidth, double prefHeight) {
-        super(text);
-        setPrefSize(prefWidth, prefHeight);
-        initialize();
-    }
-
-    public MFXButton(String text, Node graphic) {
-        super(text, graphic);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-    private void initialize() {
-        getStyleClass().add(STYLE_CLASS);
-        setAlignment(Pos.CENTER);
-        setupRippleGenerator();
-    }
-
-    public MFXCircleRippleGenerator getRippleGenerator() {
-        return this.rippleGenerator;
-    }
-
-    //================================================================================
-    // Ripple properties
-    //================================================================================
-    private final BooleanProperty computeRadiusMultiplier = new SimpleBooleanProperty(rippleGenerator.isComputeRadiusMultiplier());
-    private final BooleanProperty rippleAnimateBackground = new SimpleBooleanProperty(rippleGenerator.isAnimateBackground());
-    private final BooleanProperty rippleAnimateShadow = new SimpleBooleanProperty(rippleGenerator.isAnimateShadow());
-    private final DoubleProperty rippleAnimationSpeed = new SimpleDoubleProperty(rippleGenerator.getAnimationSpeed());
-    private final DoubleProperty rippleBackgroundOpacity = new SimpleDoubleProperty(rippleGenerator.getBackgroundOpacity());
-    private final ObjectProperty<Paint> rippleColor = new SimpleObjectProperty<>(rippleGenerator.getRippleColor());
-    private final DoubleProperty rippleRadius = new SimpleDoubleProperty(rippleGenerator.getRippleRadius());
-    private final DoubleProperty rippleRadiusMultiplier = new SimpleDoubleProperty(rippleGenerator.getRadiusMultiplier());
-
-    /**
-     * Binds the button's ripple properties to the ripple generator ones.
-     */
-    protected void setupRippleGenerator() {
-        MFXCircleRippleGenerator rippleGenerator = getRippleGenerator();
-
-        rippleGenerator.rippleColorProperty().bindBidirectional(rippleColorProperty());
-        rippleGenerator.rippleRadiusProperty().bindBidirectional(rippleRadiusProperty());
-        rippleGenerator.animationSpeedProperty().bindBidirectional(rippleAnimationSpeedProperty());
-        rippleGenerator.backgroundOpacityProperty().bindBidirectional(rippleBackgroundOpacityProperty());
-        rippleGenerator.radiusMultiplierProperty().bind(rippleRadiusMultiplierProperty());
-        rippleGenerator.computeRadiusMultiplierProperty().bind(computeRadiusMultiplierProperty());
-        rippleGenerator.animateBackgroundProperty().bind(rippleAnimateBackgroundProperty());
-        rippleGenerator.animateShadowProperty().bind(rippleAnimateShadowProperty());
-
-        setRippleColor(Color.rgb(190, 190, 190));
-        setRippleRadius(25);
-        setComputeRadiusMultiplier(true);
-        rippleGenerator.setRipplePositionFunction(event -> PositionBean.of(event.getX(), event.getY()));
-    }
-
-    public boolean isComputeRadiusMultiplier() {
-        return computeRadiusMultiplier.get();
-    }
-
-    /**
-     * Specifies if the {@link #rippleRadiusMultiplierProperty()} should be computed automatically.
-     *
-     * @see MFXCircleRippleGenerator
-     */
-    public BooleanProperty computeRadiusMultiplierProperty() {
-        return computeRadiusMultiplier;
-    }
-
-    public void setComputeRadiusMultiplier(boolean computeRadiusMultiplier) {
-        this.computeRadiusMultiplier.set(computeRadiusMultiplier);
-    }
-
-    public boolean isRippleAnimateBackground() {
-        return rippleAnimateBackground.get();
-    }
-
-    /**
-     * Specifies if the button's background should also be animated.
-     */
-    public BooleanProperty rippleAnimateBackgroundProperty() {
-        return rippleAnimateBackground;
-    }
-
-    public void setRippleAnimateBackground(boolean rippleAnimateBackground) {
-        this.rippleAnimateBackground.set(rippleAnimateBackground);
-    }
-
-    public boolean isRippleAnimateShadow() {
-        return rippleAnimateShadow.get();
-    }
-
-    /**
-     * Specifies if the button's shadow should also be animated.
-     */
-    public BooleanProperty rippleAnimateShadowProperty() {
-        return rippleAnimateShadow;
-    }
-
-    public void setRippleAnimateShadow(boolean rippleAnimateShadow) {
-        this.rippleAnimateShadow.set(rippleAnimateShadow);
-    }
-
-    public double getRippleAnimationSpeed() {
-        return rippleAnimationSpeed.get();
-    }
-
-    /**
-     * Specifies the ripple generator's animations speed.
-     */
-    public DoubleProperty rippleAnimationSpeedProperty() {
-        return rippleAnimationSpeed;
-    }
-
-    public void setRippleAnimationSpeed(double rippleAnimationSpeed) {
-        this.rippleAnimationSpeed.set(rippleAnimationSpeed);
-    }
-
-    public double getRippleBackgroundOpacity() {
-        return rippleBackgroundOpacity.get();
-    }
-
-    /**
-     * Specifies the opacity for the background animation. (if {@link #rippleAnimateBackgroundProperty()} is true).
-     */
-    public DoubleProperty rippleBackgroundOpacityProperty() {
-        return rippleBackgroundOpacity;
-    }
-
-    public void setRippleBackgroundOpacity(double rippleBackgroundOpacity) {
-        this.rippleBackgroundOpacity.set(rippleBackgroundOpacity);
-    }
-
-    public final Paint getRippleColor() {
-        return rippleColor.get();
-    }
-
-    /**
-     * Specifies the ripples color of this control.
-     */
-    public final ObjectProperty<Paint> rippleColorProperty() {
-        return this.rippleColor;
-    }
-
-    public final void setRippleColor(Paint rippleColor) {
-        this.rippleColor.set(rippleColor);
-    }
-
-    public double getRippleRadius() {
-        return rippleRadius.get();
-    }
-
-    /**
-     * Specifies the radius of the ripples.
-     */
-    public DoubleProperty rippleRadiusProperty() {
-        return rippleRadius;
-    }
-
-    public void setRippleRadius(double rippleRadius) {
-        this.rippleRadius.set(rippleRadius);
-    }
-
-    public double getRippleRadiusMultiplier() {
-        return rippleRadiusMultiplier.get();
-    }
-
-    /**
-     * Specifies the number by which the ripples' radius will be multiplied.
-     *
-     * @see MFXCircleRippleGenerator
-     */
-    public DoubleProperty rippleRadiusMultiplierProperty() {
-        return rippleRadiusMultiplier;
-    }
-
-    public void setRippleRadiusMultiplier(double rippleRadiusMultiplier) {
-        this.rippleRadiusMultiplier.set(rippleRadiusMultiplier);
-    }
-
-    //================================================================================
-    // Styleable Properties
-    //================================================================================
-    private final StyleableObjectProperty<DepthLevel> depthLevel = new SimpleStyleableObjectProperty<>(
-            StyleableProperties.DEPTH_LEVEL,
-            this,
-            "depthLevel",
-            DepthLevel.LEVEL2
-    );
-
-    private final StyleableObjectProperty<ButtonType> buttonType = new SimpleStyleableObjectProperty<>(
-            StyleableProperties.BUTTON_TYPE,
-            this,
-            "buttonType",
-            ButtonType.FLAT
-    ) {
-        @Override
-        public void set(ButtonType v) {
-            if (v == ButtonType.FLAT) setEffect(null);
-            super.set(v);
-        }
-    };
-
-    public DepthLevel getDepthLevel() {
-        return depthLevel.get();
-    }
-
-    /**
-     * Specifies how intense is the {@code DropShadow} effect applied to this control.
-     * <p>
-     * The {@code DropShadow} effect is used to make the control appear {@code RAISED}.
-     *
-     * @see io.github.palexdev.materialfx.effects.MFXDepthManager
-     */
-    public StyleableObjectProperty<DepthLevel> depthLevelProperty() {
-        return depthLevel;
-    }
-
-    public void setDepthLevel(DepthLevel depthLevel) {
-        this.depthLevel.set(depthLevel);
-    }
-
-    public ButtonType getButtonType() {
-        return buttonType.get();
-    }
-
-    /**
-     * Specifies the appearance of this control. According to material design there are two types of buttons:
-     * <p>
-     * - {@code FLAT}
-     * <p>
-     * - {@code RAISED}
-     * <p></p>
-     * If the new type is {@code FLAT} then setEffect(null) is called so that a user can also
-     * specify it's own effects for the button.
-     */
-    public StyleableObjectProperty<ButtonType> buttonTypeProperty() {
-        return buttonType;
-    }
-
-    public void setButtonType(ButtonType buttonType) {
-        this.buttonType.set(buttonType);
-    }
-
-    //================================================================================
-    // CssMetaData
-    //================================================================================
-    private static class StyleableProperties {
-        private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
-
-        private static final CssMetaData<MFXButton, DepthLevel> DEPTH_LEVEL =
-                FACTORY.createEnumCssMetaData(
-                        DepthLevel.class,
-                        "-mfx-depth-level",
-                        MFXButton::depthLevelProperty,
-                        DepthLevel.LEVEL2
-                );
-
-        private static final CssMetaData<MFXButton, ButtonType> BUTTON_TYPE =
-                FACTORY.createEnumCssMetaData(
-                        ButtonType.class,
-                        "-mfx-button-type",
-                        MFXButton::buttonTypeProperty,
-                        ButtonType.FLAT);
-
-        static {
-            cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
-                    Button.getClassCssMetaData(),
-                    DEPTH_LEVEL, BUTTON_TYPE
-            );
-        }
-
-    }
-
-    public static List<CssMetaData<? extends Styleable, ?>> getControlCssMetaDataList() {
-        return StyleableProperties.cssMetaDataList;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new MFXButtonSkin(this);
-    }
-
-    @Override
-    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
-        return MFXButton.getControlCssMetaDataList();
-    }
-
-    @Override
-    public String getUserAgentStylesheet() {
-        return STYLESHEET;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private static final StyleablePropertyFactory<MFXButton> FACTORY = new StyleablePropertyFactory<>(Button.getClassCssMetaData());
+	private final String STYLE_CLASS = "mfx-button";
+	private final String STYLESHEET = MFXResourcesLoader.load("css/MFXButton.css");
+	private final MFXCircleRippleGenerator rippleGenerator = new MFXCircleRippleGenerator(this);
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXButton() {
+		setText("Button");
+		initialize();
+	}
+
+	public MFXButton(String text) {
+		super(text);
+		initialize();
+	}
+
+	public MFXButton(String text, double prefWidth, double prefHeight) {
+		super(text);
+		setPrefSize(prefWidth, prefHeight);
+		initialize();
+	}
+
+	public MFXButton(String text, Node graphic) {
+		super(text, graphic);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+	private void initialize() {
+		getStyleClass().add(STYLE_CLASS);
+		setAlignment(Pos.CENTER);
+		setupRippleGenerator();
+	}
+
+	public MFXCircleRippleGenerator getRippleGenerator() {
+		return this.rippleGenerator;
+	}
+
+	//================================================================================
+	// Ripple properties
+	//================================================================================
+	private final BooleanProperty computeRadiusMultiplier = new SimpleBooleanProperty(rippleGenerator.isComputeRadiusMultiplier());
+	private final BooleanProperty rippleAnimateBackground = new SimpleBooleanProperty(rippleGenerator.isAnimateBackground());
+	private final BooleanProperty rippleAnimateShadow = new SimpleBooleanProperty(rippleGenerator.isAnimateShadow());
+	private final DoubleProperty rippleAnimationSpeed = new SimpleDoubleProperty(rippleGenerator.getAnimationSpeed());
+	private final DoubleProperty rippleBackgroundOpacity = new SimpleDoubleProperty(rippleGenerator.getBackgroundOpacity());
+	private final ObjectProperty<Paint> rippleColor = new SimpleObjectProperty<>(rippleGenerator.getRippleColor());
+	private final DoubleProperty rippleRadius = new SimpleDoubleProperty(rippleGenerator.getRippleRadius());
+	private final DoubleProperty rippleRadiusMultiplier = new SimpleDoubleProperty(rippleGenerator.getRadiusMultiplier());
+
+	/**
+	 * Binds the button's ripple properties to the ripple generator ones.
+	 */
+	protected void setupRippleGenerator() {
+		MFXCircleRippleGenerator rippleGenerator = getRippleGenerator();
+
+		rippleGenerator.rippleColorProperty().bindBidirectional(rippleColorProperty());
+		rippleGenerator.rippleRadiusProperty().bindBidirectional(rippleRadiusProperty());
+		rippleGenerator.animationSpeedProperty().bindBidirectional(rippleAnimationSpeedProperty());
+		rippleGenerator.backgroundOpacityProperty().bindBidirectional(rippleBackgroundOpacityProperty());
+		rippleGenerator.radiusMultiplierProperty().bind(rippleRadiusMultiplierProperty());
+		rippleGenerator.computeRadiusMultiplierProperty().bind(computeRadiusMultiplierProperty());
+		rippleGenerator.animateBackgroundProperty().bind(rippleAnimateBackgroundProperty());
+		rippleGenerator.animateShadowProperty().bind(rippleAnimateShadowProperty());
+
+		setRippleColor(Color.rgb(190, 190, 190));
+		setRippleRadius(25);
+		setComputeRadiusMultiplier(true);
+		rippleGenerator.setRipplePositionFunction(event -> PositionBean.of(event.getX(), event.getY()));
+	}
+
+	public boolean isComputeRadiusMultiplier() {
+		return computeRadiusMultiplier.get();
+	}
+
+	/**
+	 * Specifies if the {@link #rippleRadiusMultiplierProperty()} should be computed automatically.
+	 *
+	 * @see MFXCircleRippleGenerator
+	 */
+	public BooleanProperty computeRadiusMultiplierProperty() {
+		return computeRadiusMultiplier;
+	}
+
+	public void setComputeRadiusMultiplier(boolean computeRadiusMultiplier) {
+		this.computeRadiusMultiplier.set(computeRadiusMultiplier);
+	}
+
+	public boolean isRippleAnimateBackground() {
+		return rippleAnimateBackground.get();
+	}
+
+	/**
+	 * Specifies if the button's background should also be animated.
+	 */
+	public BooleanProperty rippleAnimateBackgroundProperty() {
+		return rippleAnimateBackground;
+	}
+
+	public void setRippleAnimateBackground(boolean rippleAnimateBackground) {
+		this.rippleAnimateBackground.set(rippleAnimateBackground);
+	}
+
+	public boolean isRippleAnimateShadow() {
+		return rippleAnimateShadow.get();
+	}
+
+	/**
+	 * Specifies if the button's shadow should also be animated.
+	 */
+	public BooleanProperty rippleAnimateShadowProperty() {
+		return rippleAnimateShadow;
+	}
+
+	public void setRippleAnimateShadow(boolean rippleAnimateShadow) {
+		this.rippleAnimateShadow.set(rippleAnimateShadow);
+	}
+
+	public double getRippleAnimationSpeed() {
+		return rippleAnimationSpeed.get();
+	}
+
+	/**
+	 * Specifies the ripple generator's animations speed.
+	 */
+	public DoubleProperty rippleAnimationSpeedProperty() {
+		return rippleAnimationSpeed;
+	}
+
+	public void setRippleAnimationSpeed(double rippleAnimationSpeed) {
+		this.rippleAnimationSpeed.set(rippleAnimationSpeed);
+	}
+
+	public double getRippleBackgroundOpacity() {
+		return rippleBackgroundOpacity.get();
+	}
+
+	/**
+	 * Specifies the opacity for the background animation. (if {@link #rippleAnimateBackgroundProperty()} is true).
+	 */
+	public DoubleProperty rippleBackgroundOpacityProperty() {
+		return rippleBackgroundOpacity;
+	}
+
+	public void setRippleBackgroundOpacity(double rippleBackgroundOpacity) {
+		this.rippleBackgroundOpacity.set(rippleBackgroundOpacity);
+	}
+
+	public final Paint getRippleColor() {
+		return rippleColor.get();
+	}
+
+	/**
+	 * Specifies the ripples color of this control.
+	 */
+	public final ObjectProperty<Paint> rippleColorProperty() {
+		return this.rippleColor;
+	}
+
+	public final void setRippleColor(Paint rippleColor) {
+		this.rippleColor.set(rippleColor);
+	}
+
+	public double getRippleRadius() {
+		return rippleRadius.get();
+	}
+
+	/**
+	 * Specifies the radius of the ripples.
+	 */
+	public DoubleProperty rippleRadiusProperty() {
+		return rippleRadius;
+	}
+
+	public void setRippleRadius(double rippleRadius) {
+		this.rippleRadius.set(rippleRadius);
+	}
+
+	public double getRippleRadiusMultiplier() {
+		return rippleRadiusMultiplier.get();
+	}
+
+	/**
+	 * Specifies the number by which the ripples' radius will be multiplied.
+	 *
+	 * @see MFXCircleRippleGenerator
+	 */
+	public DoubleProperty rippleRadiusMultiplierProperty() {
+		return rippleRadiusMultiplier;
+	}
+
+	public void setRippleRadiusMultiplier(double rippleRadiusMultiplier) {
+		this.rippleRadiusMultiplier.set(rippleRadiusMultiplier);
+	}
+
+	//================================================================================
+	// Styleable Properties
+	//================================================================================
+	private final StyleableObjectProperty<DepthLevel> depthLevel = new SimpleStyleableObjectProperty<>(
+			StyleableProperties.DEPTH_LEVEL,
+			this,
+			"depthLevel",
+			DepthLevel.LEVEL2
+	);
+
+	private final StyleableObjectProperty<ButtonType> buttonType = new SimpleStyleableObjectProperty<>(
+			StyleableProperties.BUTTON_TYPE,
+			this,
+			"buttonType",
+			ButtonType.FLAT
+	) {
+		@Override
+		public void set(ButtonType v) {
+			if (v == ButtonType.FLAT) setEffect(null);
+			super.set(v);
+		}
+	};
+
+	public DepthLevel getDepthLevel() {
+		return depthLevel.get();
+	}
+
+	/**
+	 * Specifies how intense is the {@code DropShadow} effect applied to this control.
+	 * <p>
+	 * The {@code DropShadow} effect is used to make the control appear {@code RAISED}.
+	 *
+	 * @see io.github.palexdev.materialfx.effects.MFXDepthManager
+	 */
+	public StyleableObjectProperty<DepthLevel> depthLevelProperty() {
+		return depthLevel;
+	}
+
+	public void setDepthLevel(DepthLevel depthLevel) {
+		this.depthLevel.set(depthLevel);
+	}
+
+	public ButtonType getButtonType() {
+		return buttonType.get();
+	}
+
+	/**
+	 * Specifies the appearance of this control. According to material design there are two types of buttons:
+	 * <p>
+	 * - {@code FLAT}
+	 * <p>
+	 * - {@code RAISED}
+	 * <p></p>
+	 * If the new type is {@code FLAT} then setEffect(null) is called so that a user can also
+	 * specify it's own effects for the button.
+	 */
+	public StyleableObjectProperty<ButtonType> buttonTypeProperty() {
+		return buttonType;
+	}
+
+	public void setButtonType(ButtonType buttonType) {
+		this.buttonType.set(buttonType);
+	}
+
+	//================================================================================
+	// CssMetaData
+	//================================================================================
+	private static class StyleableProperties {
+		private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
+
+		private static final CssMetaData<MFXButton, DepthLevel> DEPTH_LEVEL =
+				FACTORY.createEnumCssMetaData(
+						DepthLevel.class,
+						"-mfx-depth-level",
+						MFXButton::depthLevelProperty,
+						DepthLevel.LEVEL2
+				);
+
+		private static final CssMetaData<MFXButton, ButtonType> BUTTON_TYPE =
+				FACTORY.createEnumCssMetaData(
+						ButtonType.class,
+						"-mfx-button-type",
+						MFXButton::buttonTypeProperty,
+						ButtonType.FLAT);
+
+		static {
+			cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
+					Button.getClassCssMetaData(),
+					DEPTH_LEVEL, BUTTON_TYPE
+			);
+		}
+
+	}
+
+	public static List<CssMetaData<? extends Styleable, ?>> getControlCssMetaDataList() {
+		return StyleableProperties.cssMetaDataList;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new MFXButtonSkin(this);
+	}
+
+	@Override
+	public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
+		return MFXButton.getControlCssMetaDataList();
+	}
+
+	@Override
+	public String getUserAgentStylesheet() {
+		return STYLESHEET;
+	}
 }

+ 189 - 189
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckListView.java

@@ -59,193 +59,193 @@ import java.util.function.Function;
  * changes, or changes occur in the items list.
  */
 public class MFXCheckListView<T> extends AbstractMFXListView<T, MFXCheckListCell<T>> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final String STYLE_CLASS = "mfx-check-list-view";
-    private final String STYLESHEET = MFXResourcesLoader.load("css/MFXCheckListView.css");
-    private final SimpleVirtualFlow<T, MFXCheckListCell<T>> virtualFlow;
-    private final ListChangeListener<? super T> itemsChanged = this::itemsChanged;
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXCheckListView() {
-        virtualFlow = new SimpleVirtualFlow<>(
-                itemsProperty(),
-                null,
-                Orientation.VERTICAL
-        );
-        initialize();
-    }
-
-    public MFXCheckListView(ObservableList<T> items) {
-        super(items);
-        virtualFlow = new SimpleVirtualFlow<>(
-                itemsProperty(),
-                null,
-                Orientation.VERTICAL
-        );
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-    @Override
-    protected void initialize() {
-        super.initialize();
-        getStyleClass().add(STYLE_CLASS);
-        items.addListener((observable, oldValue, newValue) -> {
-            oldValue.removeListener(itemsChanged);
-            newValue.addListener(itemsChanged);
-        });
-        getItems().addListener(this::itemsChanged);
-    }
-
-    protected void itemsChanged(ListChangeListener.Change<? extends T> change) {
-        if (getSelectionModel().getSelection().isEmpty()) return;
-
-        if (change.getList().isEmpty()) {
-            getSelectionModel().clearSelection();
-            return;
-        }
-
-        ListChangeHelper.Change c = ListChangeHelper.processChange(change, NumberRange.of(0, Integer.MAX_VALUE));
-        ListChangeProcessor updater = new ListChangeProcessor(new HashSet<>(getSelectionModel().getSelection().keySet()));
-        c.processReplacement((changed, removed) -> getSelectionModel().replaceSelection(changed.toArray(new Integer[0])));
-        c.processAddition((from, to, added) -> {
-            updater.computeAddition(added.size(), from);
-            getSelectionModel().replaceSelection(updater.getIndexes().toArray(new Integer[0]));
-        });
-        c.processRemoval((from, to, removed) -> {
-            updater.computeRemoval(removed, from);
-            getSelectionModel().replaceSelection(updater.getIndexes().toArray(new Integer[0]));
-        });
-    }
-
-    //================================================================================
-    // Delegate Methods
-    //================================================================================
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#getCell(int)}.
-     */
-    public MFXCheckListCell<T> getCell(int index) {
-        return virtualFlow.getCell(index);
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#getCells()}.
-     */
-    public Map<Integer, MFXCheckListCell<T>> getCells() {
-        return virtualFlow.getCells();
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#scrollBy(double)}.
-     */
-    public void scrollBy(double pixels) {
-        virtualFlow.scrollBy(pixels);
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#scrollTo(int)}.
-     */
-    public void scrollTo(int index) {
-        virtualFlow.scrollTo(index);
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#scrollToFirst()}.
-     */
-    public void scrollToFirst() {
-        virtualFlow.scrollToFirst();
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#scrollToLast()}.
-     */
-    public void scrollToLast() {
-        virtualFlow.scrollToLast();
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#scrollToPixel(double)}.
-     */
-    public void scrollToPixel(double pixel) {
-        virtualFlow.scrollToPixel(pixel);
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#setHSpeed(double, double)}.
-     */
-    public void setHSpeed(double unit, double block) {
-        virtualFlow.setHSpeed(unit, block);
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#setVSpeed(double, double)}.
-     */
-    public void setVSpeed(double unit, double block) {
-        virtualFlow.setVSpeed(unit, block);
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#getVerticalPosition()}.
-     */
-    public double getVerticalPosition() {
-        return virtualFlow.getVerticalPosition();
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#getHorizontalPosition()}.
-     */
-    public double getHorizontalPosition() {
-        return virtualFlow.getHorizontalPosition();
-    }
-
-    /**
-     * Delegate method for {@link SimpleVirtualFlow#features()}.
-     */
-    public SimpleVirtualFlow<T, MFXCheckListCell<T>>.Features features() {
-        return virtualFlow.features();
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-
-    /**
-     * Sets the default factory for the cells.
-     */
-    @Override
-    protected void setDefaultCellFactory() {
-        setCellFactory(item -> new MFXCheckListCell<>(this, item));
-    }
-
-    @Override
-    public Function<T, MFXCheckListCell<T>> getCellFactory() {
-        return virtualFlow.getCellFactory();
-    }
-
-    @Override
-    public ObjectProperty<Function<T, MFXCheckListCell<T>>> cellFactoryProperty() {
-        return virtualFlow.cellFactoryProperty();
-    }
-
-    @Override
-    public void setCellFactory(Function<T, MFXCheckListCell<T>> cellFactory) {
-        virtualFlow.setCellFactory(cellFactory);
-    }
-
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new MFXListViewSkin<>(this, virtualFlow);
-    }
-
-    @Override
-    public String getUserAgentStylesheet() {
-        return STYLESHEET;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final String STYLE_CLASS = "mfx-check-list-view";
+	private final String STYLESHEET = MFXResourcesLoader.load("css/MFXCheckListView.css");
+	private final SimpleVirtualFlow<T, MFXCheckListCell<T>> virtualFlow;
+	private final ListChangeListener<? super T> itemsChanged = this::itemsChanged;
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXCheckListView() {
+		virtualFlow = new SimpleVirtualFlow<>(
+				itemsProperty(),
+				null,
+				Orientation.VERTICAL
+		);
+		initialize();
+	}
+
+	public MFXCheckListView(ObservableList<T> items) {
+		super(items);
+		virtualFlow = new SimpleVirtualFlow<>(
+				itemsProperty(),
+				null,
+				Orientation.VERTICAL
+		);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+	@Override
+	protected void initialize() {
+		super.initialize();
+		getStyleClass().add(STYLE_CLASS);
+		items.addListener((observable, oldValue, newValue) -> {
+			oldValue.removeListener(itemsChanged);
+			newValue.addListener(itemsChanged);
+		});
+		getItems().addListener(this::itemsChanged);
+	}
+
+	protected void itemsChanged(ListChangeListener.Change<? extends T> change) {
+		if (getSelectionModel().getSelection().isEmpty()) return;
+
+		if (change.getList().isEmpty()) {
+			getSelectionModel().clearSelection();
+			return;
+		}
+
+		ListChangeHelper.Change c = ListChangeHelper.processChange(change, NumberRange.of(0, Integer.MAX_VALUE));
+		ListChangeProcessor updater = new ListChangeProcessor(new HashSet<>(getSelectionModel().getSelection().keySet()));
+		c.processReplacement((changed, removed) -> getSelectionModel().replaceSelection(changed.toArray(new Integer[0])));
+		c.processAddition((from, to, added) -> {
+			updater.computeAddition(added.size(), from);
+			getSelectionModel().replaceSelection(updater.getIndexes().toArray(new Integer[0]));
+		});
+		c.processRemoval((from, to, removed) -> {
+			updater.computeRemoval(removed, from);
+			getSelectionModel().replaceSelection(updater.getIndexes().toArray(new Integer[0]));
+		});
+	}
+
+	//================================================================================
+	// Delegate Methods
+	//================================================================================
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#getCell(int)}.
+	 */
+	public MFXCheckListCell<T> getCell(int index) {
+		return virtualFlow.getCell(index);
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#getCells()}.
+	 */
+	public Map<Integer, MFXCheckListCell<T>> getCells() {
+		return virtualFlow.getCells();
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#scrollBy(double)}.
+	 */
+	public void scrollBy(double pixels) {
+		virtualFlow.scrollBy(pixels);
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#scrollTo(int)}.
+	 */
+	public void scrollTo(int index) {
+		virtualFlow.scrollTo(index);
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#scrollToFirst()}.
+	 */
+	public void scrollToFirst() {
+		virtualFlow.scrollToFirst();
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#scrollToLast()}.
+	 */
+	public void scrollToLast() {
+		virtualFlow.scrollToLast();
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#scrollToPixel(double)}.
+	 */
+	public void scrollToPixel(double pixel) {
+		virtualFlow.scrollToPixel(pixel);
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#setHSpeed(double, double)}.
+	 */
+	public void setHSpeed(double unit, double block) {
+		virtualFlow.setHSpeed(unit, block);
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#setVSpeed(double, double)}.
+	 */
+	public void setVSpeed(double unit, double block) {
+		virtualFlow.setVSpeed(unit, block);
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#getVerticalPosition()}.
+	 */
+	public double getVerticalPosition() {
+		return virtualFlow.getVerticalPosition();
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#getHorizontalPosition()}.
+	 */
+	public double getHorizontalPosition() {
+		return virtualFlow.getHorizontalPosition();
+	}
+
+	/**
+	 * Delegate method for {@link SimpleVirtualFlow#features()}.
+	 */
+	public SimpleVirtualFlow<T, MFXCheckListCell<T>>.Features features() {
+		return virtualFlow.features();
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+
+	/**
+	 * Sets the default factory for the cells.
+	 */
+	@Override
+	protected void setDefaultCellFactory() {
+		setCellFactory(item -> new MFXCheckListCell<>(this, item));
+	}
+
+	@Override
+	public Function<T, MFXCheckListCell<T>> getCellFactory() {
+		return virtualFlow.getCellFactory();
+	}
+
+	@Override
+	public ObjectProperty<Function<T, MFXCheckListCell<T>>> cellFactoryProperty() {
+		return virtualFlow.cellFactoryProperty();
+	}
+
+	@Override
+	public void setCellFactory(Function<T, MFXCheckListCell<T>> cellFactory) {
+		virtualFlow.setCellFactory(cellFactory);
+	}
+
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new MFXListViewSkin<>(this, virtualFlow);
+	}
+
+	@Override
+	public String getUserAgentStylesheet() {
+		return STYLESHEET;
+	}
 }

+ 129 - 129
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckTreeItem.java

@@ -44,133 +44,133 @@ import java.lang.ref.WeakReference;
  * @see ITreeCheckModel
  */
 public class MFXCheckTreeItem<T> extends MFXTreeItem<T> {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final String STYLE_CLASS = "mfx-check-tree-item";
-    private final String STYLESHEET = MFXResourcesLoader.load("css/MFXTreeItem.css");
-
-    private final BooleanProperty checked = new SimpleBooleanProperty(false);
-    private final BooleanProperty indeterminate = new SimpleBooleanProperty(false);
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXCheckTreeItem(T data) {
-        super(data);
-        initialize();
-    }
-
-    public MFXCheckTreeItem(T data, Callback<AbstractMFXTreeItem<T>, AbstractMFXTreeCell<T>> cellFactory) {
-        super(data, cellFactory);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Sets the style class to "mfx-tree-view".
-     * <p>
-     * Adds a listener to {@link #treeViewProperty()} allowing item check before the Scene is shown
-     * by calling the TreeCheckModel {@link TreeCheckModel#scanTree(MFXCheckTreeItem)} )} method.
-     */
-    private void initialize() {
-        getStyleClass().add(STYLE_CLASS);
-
-        treeViewProperty().addListener((observable, oldValue, newValue) -> {
-            if (newValue != null && isRoot()) {
-                TreeCheckModel<T> treeCheckModel = (TreeCheckModel<T>) getSelectionModel();
-                treeCheckModel.scanTree((MFXCheckTreeItem<T>) getRoot());
-            }
-        });
-    }
-
-    public boolean isChecked() {
-        return checked.get();
-    }
-
-    public BooleanProperty checkedProperty() {
-        return checked;
-    }
-
-    public void setChecked(boolean checked) {
-        this.checked.set(checked);
-    }
-
-    public boolean isIndeterminate() {
-        return indeterminate.get();
-    }
-
-    public BooleanProperty indeterminateProperty() {
-        return indeterminate;
-    }
-
-    public void setIndeterminate(boolean indeterminate) {
-        this.indeterminate.set(indeterminate);
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-
-    /**
-     * Overridden to return the ITreeCheckModel instance of the MFXCheckTreeView.
-     */
-    @Override
-    public ITreeCheckModel<T> getSelectionModel() {
-        return (ITreeCheckModel<T>) super.getSelectionModel();
-    }
-
-    /**
-     * Overridden to use {@link MFXCheckTreeCell}.
-     */
-    @Override
-    protected void defaultCellFactory() {
-        super.cellFactory.set(cell -> new MFXCheckTreeCell<>(this));
-    }
-
-    /**
-     * Overridden to use {@link MFXCheckTreeItemSkin}.
-     */
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new MFXCheckTreeItemSkin<>(this);
-    }
-
-    @Override
-    public String getUserAgentStylesheet() {
-        return STYLESHEET;
-    }
-
-    //================================================================================
-    // Events
-    //================================================================================
-
-    /**
-     * Events class for the items.
-     * <p>
-     * Defines a new EventTypes:
-     * <p>
-     * - CHECK_EVENT: when an item is checked/unchecked, the item and all the parents up to the root should adjust their state accordingly. <p></p>
-     * <p>
-     * Note on constructor: when we fire an event we pass the item reference to distinguish between the item on which the item is fired and the parents.
-     * <p>
-     * Of course these events are for internal use only so they should not be used by users.
-     */
-    public static final class CheckTreeItemEvent<T> extends Event {
-        private final WeakReference<AbstractMFXTreeItem<T>> itemRef;
-
-        public static final EventType<CheckTreeItemEvent<?>> CHECK_EVENT = new EventType<>(ANY, "CHECK_EVENT");
-
-        public CheckTreeItemEvent(EventType<? extends Event> eventType, AbstractMFXTreeItem<T> item) {
-            super(eventType);
-            this.itemRef = new WeakReference<>(item);
-        }
-
-        public AbstractMFXTreeItem<T> getItemRef() {
-            return itemRef.get();
-        }
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final String STYLE_CLASS = "mfx-check-tree-item";
+	private final String STYLESHEET = MFXResourcesLoader.load("css/MFXTreeItem.css");
+
+	private final BooleanProperty checked = new SimpleBooleanProperty(false);
+	private final BooleanProperty indeterminate = new SimpleBooleanProperty(false);
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXCheckTreeItem(T data) {
+		super(data);
+		initialize();
+	}
+
+	public MFXCheckTreeItem(T data, Callback<AbstractMFXTreeItem<T>, AbstractMFXTreeCell<T>> cellFactory) {
+		super(data, cellFactory);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Sets the style class to "mfx-tree-view".
+	 * <p>
+	 * Adds a listener to {@link #treeViewProperty()} allowing item check before the Scene is shown
+	 * by calling the TreeCheckModel {@link TreeCheckModel#scanTree(MFXCheckTreeItem)} )} method.
+	 */
+	private void initialize() {
+		getStyleClass().add(STYLE_CLASS);
+
+		treeViewProperty().addListener((observable, oldValue, newValue) -> {
+			if (newValue != null && isRoot()) {
+				TreeCheckModel<T> treeCheckModel = (TreeCheckModel<T>) getSelectionModel();
+				treeCheckModel.scanTree((MFXCheckTreeItem<T>) getRoot());
+			}
+		});
+	}
+
+	public boolean isChecked() {
+		return checked.get();
+	}
+
+	public BooleanProperty checkedProperty() {
+		return checked;
+	}
+
+	public void setChecked(boolean checked) {
+		this.checked.set(checked);
+	}
+
+	public boolean isIndeterminate() {
+		return indeterminate.get();
+	}
+
+	public BooleanProperty indeterminateProperty() {
+		return indeterminate;
+	}
+
+	public void setIndeterminate(boolean indeterminate) {
+		this.indeterminate.set(indeterminate);
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+
+	/**
+	 * Overridden to return the ITreeCheckModel instance of the MFXCheckTreeView.
+	 */
+	@Override
+	public ITreeCheckModel<T> getSelectionModel() {
+		return (ITreeCheckModel<T>) super.getSelectionModel();
+	}
+
+	/**
+	 * Overridden to use {@link MFXCheckTreeCell}.
+	 */
+	@Override
+	protected void defaultCellFactory() {
+		super.cellFactory.set(cell -> new MFXCheckTreeCell<>(this));
+	}
+
+	/**
+	 * Overridden to use {@link MFXCheckTreeItemSkin}.
+	 */
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new MFXCheckTreeItemSkin<>(this);
+	}
+
+	@Override
+	public String getUserAgentStylesheet() {
+		return STYLESHEET;
+	}
+
+	//================================================================================
+	// Events
+	//================================================================================
+
+	/**
+	 * Events class for the items.
+	 * <p>
+	 * Defines a new EventTypes:
+	 * <p>
+	 * - CHECK_EVENT: when an item is checked/unchecked, the item and all the parents up to the root should adjust their state accordingly. <p></p>
+	 * <p>
+	 * Note on constructor: when we fire an event we pass the item reference to distinguish between the item on which the item is fired and the parents.
+	 * <p>
+	 * Of course these events are for internal use only so they should not be used by users.
+	 */
+	public static final class CheckTreeItemEvent<T> extends Event {
+		private final WeakReference<AbstractMFXTreeItem<T>> itemRef;
+
+		public static final EventType<CheckTreeItemEvent<?>> CHECK_EVENT = new EventType<>(ANY, "CHECK_EVENT");
+
+		public CheckTreeItemEvent(EventType<? extends Event> eventType, AbstractMFXTreeItem<T> item) {
+			super(eventType);
+			this.itemRef = new WeakReference<>(item);
+		}
+
+		public AbstractMFXTreeItem<T> getItemRef() {
+			return itemRef.get();
+		}
+	}
 }

+ 29 - 29
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckTreeView.java

@@ -29,37 +29,37 @@ import io.github.palexdev.materialfx.selection.TreeCheckModel;
  * @param <T> The type of the data within the items.
  */
 public class MFXCheckTreeView<T> extends MFXTreeView<T> {
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXCheckTreeView() {
-        super();
-    }
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXCheckTreeView() {
+		super();
+	}
 
-    public MFXCheckTreeView(MFXCheckTreeItem<T> root) {
-        super(root);
-    }
+	public MFXCheckTreeView(MFXCheckTreeItem<T> root) {
+		super(root);
+	}
 
-    //================================================================================
-    // Methods
-    //================================================================================
-    public TreeCheckModel<T> getCheckModel() {
-        return (TreeCheckModel<T>) super.getSelectionModel();
-    }
+	//================================================================================
+	// Methods
+	//================================================================================
+	public TreeCheckModel<T> getCheckModel() {
+		return (TreeCheckModel<T>) super.getSelectionModel();
+	}
 
-    //================================================================================
-    // Override Methods
-    //================================================================================
+	//================================================================================
+	// Override Methods
+	//================================================================================
 
-    /**
-     * Overridden method to install a TreeCheckModel.
-     * <p>
-     * By default it is set to allow multiple selection.
-     */
-    @Override
-    protected void installSelectionModel() {
-        TreeCheckModel<T> treeCheckModel = new TreeCheckModel<>();
-        treeCheckModel.setAllowsMultipleSelection(true);
-        setSelectionModel(treeCheckModel);
-    }
+	/**
+	 * Overridden method to install a TreeCheckModel.
+	 * <p>
+	 * By default it is set to allow multiple selection.
+	 */
+	@Override
+	protected void installSelectionModel() {
+		TreeCheckModel<T> treeCheckModel = new TreeCheckModel<>();
+		treeCheckModel.setAllowsMultipleSelection(true);
+		setSelectionModel(treeCheckModel);
+	}
 }

+ 149 - 149
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckbox.java

@@ -41,153 +41,153 @@ import java.util.List;
  * <p> - {@link #textExpandProperty()}: to control the text size and the checkbox layout (see documentation)
  */
 public class MFXCheckbox extends CheckBox implements MFXLabeled {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private static final StyleablePropertyFactory<MFXCheckbox> FACTORY = new StyleablePropertyFactory<>(CheckBox.getClassCssMetaData());
-    private final String STYLE_CLASS = "mfx-checkbox";
-    private final String STYLESHEET = MFXResourcesLoader.load("css/MFXCheckBox.css");
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXCheckbox() {
-        this("");
-    }
-
-    public MFXCheckbox(String text) {
-        super(text);
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-    private void initialize() {
-        getStyleClass().add(STYLE_CLASS);
-    }
-
-    //================================================================================
-    // Stylesheet properties
-    //================================================================================
-    private final StyleableObjectProperty<ContentDisplay> contentDisposition = new SimpleStyleableObjectProperty<>(
-            StyleableProperties.CONTENT_DISPOSITION,
-            this,
-            "contentDisposition",
-            ContentDisplay.LEFT
-    ) {
-        @Override
-        public StyleOrigin getStyleOrigin() {
-            return StyleOrigin.USER_AGENT;
-        }
-    };
-
-    private final StyleableDoubleProperty gap = new SimpleStyleableDoubleProperty(
-            StyleableProperties.GAP,
-            this,
-            "gap",
-            8.0
-    );
-
-    private final StyleableBooleanProperty textExpand = new SimpleStyleableBooleanProperty(
-            StyleableProperties.TEXT_EXPAND,
-            this,
-            "textExpand",
-            false
-    );
-
-    public ContentDisplay getContentDisposition() {
-        return contentDisposition.get();
-    }
-
-    public StyleableObjectProperty<ContentDisplay> contentDispositionProperty() {
-        return contentDisposition;
-    }
-
-    public void setContentDisposition(ContentDisplay contentDisposition) {
-        this.contentDisposition.set(contentDisposition);
-    }
-
-    public double getGap() {
-        return gap.get();
-    }
-
-    public StyleableDoubleProperty gapProperty() {
-        return gap;
-    }
-
-    public void setGap(double gap) {
-        this.gap.set(gap);
-    }
-
-    public boolean isTextExpand() {
-        return textExpand.get();
-    }
-
-    public StyleableBooleanProperty textExpandProperty() {
-        return textExpand;
-    }
-
-    public void setTextExpand(boolean textExpand) {
-        this.textExpand.set(textExpand);
-    }
-
-    //================================================================================
-    // CssMetaData
-    //================================================================================
-    private static class StyleableProperties {
-        private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
-
-        private static final CssMetaData<MFXCheckbox, ContentDisplay> CONTENT_DISPOSITION =
-                FACTORY.createEnumCssMetaData(
-                        ContentDisplay.class,
-                        "-mfx-content-disposition",
-                        MFXCheckbox::contentDispositionProperty,
-                        ContentDisplay.LEFT
-                );
-
-        private static final CssMetaData<MFXCheckbox, Number> GAP =
-                FACTORY.createSizeCssMetaData(
-                        "-mfx-gap",
-                        MFXCheckbox::gapProperty,
-                        8.0
-                );
-
-        private static final CssMetaData<MFXCheckbox, Boolean> TEXT_EXPAND =
-                FACTORY.createBooleanCssMetaData(
-                        "-mfx-text-expand",
-                        MFXCheckbox::textExpandProperty,
-                        false
-                );
-
-        static {
-            cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
-                    CheckBox.getClassCssMetaData(),
-                    CONTENT_DISPOSITION, GAP, TEXT_EXPAND
-            );
-        }
-    }
-
-    public static List<CssMetaData<? extends Styleable, ?>> getControlCssMetaDataList() {
-        return StyleableProperties.cssMetaDataList;
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new MFXCheckboxSkin(this);
-    }
-
-    @Override
-    public String getUserAgentStylesheet() {
-        return STYLESHEET;
-    }
-
-    @Override
-    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
-        return MFXCheckbox.getControlCssMetaDataList();
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private static final StyleablePropertyFactory<MFXCheckbox> FACTORY = new StyleablePropertyFactory<>(CheckBox.getClassCssMetaData());
+	private final String STYLE_CLASS = "mfx-checkbox";
+	private final String STYLESHEET = MFXResourcesLoader.load("css/MFXCheckBox.css");
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXCheckbox() {
+		this("");
+	}
+
+	public MFXCheckbox(String text) {
+		super(text);
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+	private void initialize() {
+		getStyleClass().add(STYLE_CLASS);
+	}
+
+	//================================================================================
+	// Stylesheet properties
+	//================================================================================
+	private final StyleableObjectProperty<ContentDisplay> contentDisposition = new SimpleStyleableObjectProperty<>(
+			StyleableProperties.CONTENT_DISPOSITION,
+			this,
+			"contentDisposition",
+			ContentDisplay.LEFT
+	) {
+		@Override
+		public StyleOrigin getStyleOrigin() {
+			return StyleOrigin.USER_AGENT;
+		}
+	};
+
+	private final StyleableDoubleProperty gap = new SimpleStyleableDoubleProperty(
+			StyleableProperties.GAP,
+			this,
+			"gap",
+			8.0
+	);
+
+	private final StyleableBooleanProperty textExpand = new SimpleStyleableBooleanProperty(
+			StyleableProperties.TEXT_EXPAND,
+			this,
+			"textExpand",
+			false
+	);
+
+	public ContentDisplay getContentDisposition() {
+		return contentDisposition.get();
+	}
+
+	public StyleableObjectProperty<ContentDisplay> contentDispositionProperty() {
+		return contentDisposition;
+	}
+
+	public void setContentDisposition(ContentDisplay contentDisposition) {
+		this.contentDisposition.set(contentDisposition);
+	}
+
+	public double getGap() {
+		return gap.get();
+	}
+
+	public StyleableDoubleProperty gapProperty() {
+		return gap;
+	}
+
+	public void setGap(double gap) {
+		this.gap.set(gap);
+	}
+
+	public boolean isTextExpand() {
+		return textExpand.get();
+	}
+
+	public StyleableBooleanProperty textExpandProperty() {
+		return textExpand;
+	}
+
+	public void setTextExpand(boolean textExpand) {
+		this.textExpand.set(textExpand);
+	}
+
+	//================================================================================
+	// CssMetaData
+	//================================================================================
+	private static class StyleableProperties {
+		private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
+
+		private static final CssMetaData<MFXCheckbox, ContentDisplay> CONTENT_DISPOSITION =
+				FACTORY.createEnumCssMetaData(
+						ContentDisplay.class,
+						"-mfx-content-disposition",
+						MFXCheckbox::contentDispositionProperty,
+						ContentDisplay.LEFT
+				);
+
+		private static final CssMetaData<MFXCheckbox, Number> GAP =
+				FACTORY.createSizeCssMetaData(
+						"-mfx-gap",
+						MFXCheckbox::gapProperty,
+						8.0
+				);
+
+		private static final CssMetaData<MFXCheckbox, Boolean> TEXT_EXPAND =
+				FACTORY.createBooleanCssMetaData(
+						"-mfx-text-expand",
+						MFXCheckbox::textExpandProperty,
+						false
+				);
+
+		static {
+			cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
+					CheckBox.getClassCssMetaData(),
+					CONTENT_DISPOSITION, GAP, TEXT_EXPAND
+			);
+		}
+	}
+
+	public static List<CssMetaData<? extends Styleable, ?>> getControlCssMetaDataList() {
+		return StyleableProperties.cssMetaDataList;
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new MFXCheckboxSkin(this);
+	}
+
+	@Override
+	public String getUserAgentStylesheet() {
+		return STYLESHEET;
+	}
+
+	@Override
+	public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
+		return MFXCheckbox.getControlCssMetaDataList();
+	}
 }

+ 124 - 124
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXFilterPane.java

@@ -117,128 +117,128 @@ import java.util.function.Predicate;
  * @param <T>
  */
 public class MFXFilterPane<T> extends Control {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final String STYLE_CLASS = "mfx-filter-pane";
-    private final String STYLESHEET = MFXResourcesLoader.load("css/MFXFilterPane.css");
-    private final StringProperty headerText = new SimpleStringProperty("Filters");
-    private final ObservableList<AbstractFilter<T, ?>> filters = FXCollections.observableArrayList();
-    private final ObservableList<FilterBean<T, ?>> activeFilters = FXCollections.observableArrayList();
-
-    private EventHandler<MouseEvent> onFilter = event -> {};
-    private EventHandler<MouseEvent> onReset = event -> {};
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXFilterPane() {
-        initialize();
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-    private void initialize() {
-        getStyleClass().add(STYLE_CLASS);
-    }
-
-    /**
-     * Builds a predicate from the list of built filters (active filters).
-     * <p></p>
-     * The {@link FilterBean} are chained by using {@link PredicateUtils#chain(Predicate, Predicate, ChainMode)}.
-     * <p></p>
-     * If the list is empty by default a predicate that always returns true is built.
-     */
-    public Predicate<T> filter() {
-        Predicate<T> filter = null;
-        ChainMode mode = null;
-
-        for (FilterBean<T, ?> activeFilter : activeFilters) {
-            if (filter == null) {
-                filter = activeFilter.predicate();
-                mode = activeFilter.getMode();
-                continue;
-            }
-
-            filter = PredicateUtils.chain(filter, activeFilter.predicate(), mode);
-            mode = activeFilter.getMode();
-        }
-
-        return filter != null ? filter : t -> true;
-    }
-
-    //================================================================================
-    // Getters/Setters
-    //================================================================================
-    public String getHeaderText() {
-        return headerText.get();
-    }
-
-    /**
-     * Specifies the text of the header.
-     */
-    public StringProperty headerTextProperty() {
-        return headerText;
-    }
-
-    public void setHeaderText(String headerText) {
-        this.headerText.set(headerText);
-    }
-
-    /**
-     * @return the list of {@link AbstractFilter}s. Each of them
-     * represents an object's field o  which the filter operates
-     */
-    public ObservableList<AbstractFilter<T, ?>> getFilters() {
-        return filters;
-    }
-
-    /**
-     * @return the list of built filters
-     */
-    public ObservableList<FilterBean<T, ?>> getActiveFilters() {
-        return activeFilters;
-    }
-
-    /**
-     * @return the action invoked when clicking on the filter icon
-     */
-    public EventHandler<MouseEvent> getOnFilter() {
-        return onFilter;
-    }
-
-    /**
-     * Sets the action to perform when the filter icon is clicked.
-     */
-    public void setOnFilter(EventHandler<MouseEvent> onFilter) {
-        this.onFilter = onFilter;
-    }
-
-    /**
-     * @return the action invoked when clicking on the reset icon
-     */
-    public EventHandler<MouseEvent> getOnReset() {
-        return onReset;
-    }
-
-    /**
-     * Sets the action to perform when the reset icon is clicked.
-     */
-    public void setOnReset(EventHandler<MouseEvent> onReset) {
-        this.onReset = onReset;
-    }
-
-    //================================================================================
-    // Overridden Methods
-    //================================================================================
-    @Override
-    protected Skin<?> createDefaultSkin() {
-        return new MFXFilterPaneSkin<>(this);
-    }
-
-    @Override
-    public String getUserAgentStylesheet() {
-        return STYLESHEET;
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final String STYLE_CLASS = "mfx-filter-pane";
+	private final String STYLESHEET = MFXResourcesLoader.load("css/MFXFilterPane.css");
+	private final StringProperty headerText = new SimpleStringProperty("Filters");
+	private final ObservableList<AbstractFilter<T, ?>> filters = FXCollections.observableArrayList();
+	private final ObservableList<FilterBean<T, ?>> activeFilters = FXCollections.observableArrayList();
+
+	private EventHandler<MouseEvent> onFilter = event -> {};
+	private EventHandler<MouseEvent> onReset = event -> {};
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXFilterPane() {
+		initialize();
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+	private void initialize() {
+		getStyleClass().add(STYLE_CLASS);
+	}
+
+	/**
+	 * Builds a predicate from the list of built filters (active filters).
+	 * <p></p>
+	 * The {@link FilterBean} are chained by using {@link PredicateUtils#chain(Predicate, Predicate, ChainMode)}.
+	 * <p></p>
+	 * If the list is empty by default a predicate that always returns true is built.
+	 */
+	public Predicate<T> filter() {
+		Predicate<T> filter = null;
+		ChainMode mode = null;
+
+		for (FilterBean<T, ?> activeFilter : activeFilters) {
+			if (filter == null) {
+				filter = activeFilter.predicate();
+				mode = activeFilter.getMode();
+				continue;
+			}
+
+			filter = PredicateUtils.chain(filter, activeFilter.predicate(), mode);
+			mode = activeFilter.getMode();
+		}
+
+		return filter != null ? filter : t -> true;
+	}
+
+	//================================================================================
+	// Getters/Setters
+	//================================================================================
+	public String getHeaderText() {
+		return headerText.get();
+	}
+
+	/**
+	 * Specifies the text of the header.
+	 */
+	public StringProperty headerTextProperty() {
+		return headerText;
+	}
+
+	public void setHeaderText(String headerText) {
+		this.headerText.set(headerText);
+	}
+
+	/**
+	 * @return the list of {@link AbstractFilter}s. Each of them
+	 * represents an object's field o  which the filter operates
+	 */
+	public ObservableList<AbstractFilter<T, ?>> getFilters() {
+		return filters;
+	}
+
+	/**
+	 * @return the list of built filters
+	 */
+	public ObservableList<FilterBean<T, ?>> getActiveFilters() {
+		return activeFilters;
+	}
+
+	/**
+	 * @return the action invoked when clicking on the filter icon
+	 */
+	public EventHandler<MouseEvent> getOnFilter() {
+		return onFilter;
+	}
+
+	/**
+	 * Sets the action to perform when the filter icon is clicked.
+	 */
+	public void setOnFilter(EventHandler<MouseEvent> onFilter) {
+		this.onFilter = onFilter;
+	}
+
+	/**
+	 * @return the action invoked when clicking on the reset icon
+	 */
+	public EventHandler<MouseEvent> getOnReset() {
+		return onReset;
+	}
+
+	/**
+	 * Sets the action to perform when the reset icon is clicked.
+	 */
+	public void setOnReset(EventHandler<MouseEvent> onReset) {
+		this.onReset = onReset;
+	}
+
+	//================================================================================
+	// Overridden Methods
+	//================================================================================
+	@Override
+	protected Skin<?> createDefaultSkin() {
+		return new MFXFilterPaneSkin<>(this);
+	}
+
+	@Override
+	public String getUserAgentStylesheet() {
+		return STYLESHEET;
+	}
 }

+ 149 - 149
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXIconWrapper.java

@@ -47,155 +47,155 @@ import java.util.function.Function;
  * The size is equal and fixed both for height and width, can be changed via CSS.
  */
 public class MFXIconWrapper extends StackPane {
-    //================================================================================
-    // Properties
-    //================================================================================
-    private final String STYLE_CLASS = "mfx-icon-wrapper";
-
-    private final ObjectProperty<Node> icon = new SimpleObjectProperty<>();
-    private final MFXCircleRippleGenerator rippleGenerator = new MFXCircleRippleGenerator(this);
-
-    //================================================================================
-    // Constructors
-    //================================================================================
-    public MFXIconWrapper() {
-        initialize();
-    }
-
-    public MFXIconWrapper(Node icon, double size) {
-        initialize();
-
-        setIcon(icon);
-        setSize(size);
-    }
-
-    public MFXIconWrapper(String description, double iconSize, double wrapperSize) {
-        initialize();
-
-        setIcon(new MFXFontIcon(description, iconSize));
-        setSize(wrapperSize);
-    }
-
-    public MFXIconWrapper(String description, double iconSize, Color iconColor, double wrapperSize) {
-        initialize();
-
-        setIcon(new MFXFontIcon(description, iconSize, iconColor));
-        setSize(wrapperSize);
-    }
-
-    //================================================================================
-    // Methods
-    //================================================================================
-
-    /**
-     * Adds a ripple generator to the icon. It is an optional.
-     */
-    public MFXIconWrapper addRippleGenerator() {
-        if (!getChildren().contains(rippleGenerator)) {
-            super.getChildren().add(0, rippleGenerator);
-        }
-
-        return this;
-    }
-
-    /**
-     * Adds the ripple generator to the icon by calling {@link #addRippleGenerator()}, sets its position function
-     * to use the mouse event x and y coordinates, and adds the event filter to the icon to generate the ripples.
-     *
-     * @see IRippleGenerator
-     * @see MFXCircleRippleGenerator
-     */
-    public MFXIconWrapper defaultRippleGeneratorBehavior() {
-        addRippleGenerator();
-        rippleGenerator.setRipplePositionFunction(event -> PositionBean.of(event.getX(), event.getY()));
-        addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
-            if (event.getButton() == MouseButton.PRIMARY) {
-                rippleGenerator.generateRipple(event);
-            }
-        });
-        return this;
-    }
-
-    /**
-     * Adds the ripple generator to the icon by calling {@link #addRippleGenerator()}, sets its position function
-     * to the given function, and adds the event filter to the icon to generate the ripples.
-     *
-     * @see IRippleGenerator
-     * @see MFXCircleRippleGenerator
-     */
-    public MFXIconWrapper rippleGeneratorBehavior(Function<MouseEvent, PositionBean> positionFunction) {
-        addRippleGenerator();
-        rippleGenerator.setRipplePositionFunction(positionFunction);
-        addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
-            if (event.getButton() == MouseButton.PRIMARY) {
-                rippleGenerator.generateRipple(event);
-            }
-        });
-        return this;
-    }
-
-    private void initialize() {
-        getStyleClass().add(STYLE_CLASS);
-
-        setMinSize(USE_PREF_SIZE, USE_PREF_SIZE);
-        setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
-
-        icon.addListener((observable, oldValue, newValue) -> {
-            super.getChildren().remove(oldValue);
-            manageIcon(newValue);
-        });
-        size.addListener((observable, oldValue, newValue) -> setPrefSize(newValue.doubleValue(), newValue.doubleValue()));
-    }
-
-    /**
-     * This method handles the positioning of the icon in the children list.
-     */
-    private void manageIcon(Node icon) {
-        if (icon == null) {
-            return;
-        }
-
-        ObservableList<Node> children = super.getChildren();
-
-        if (children.isEmpty()) {
-            children.add(icon);
-            return;
-        }
-
-        if (children.contains(rippleGenerator)) {
-            if (children.size() == 1) {
-                children.add(icon);
-            } else {
-                children.set(1, icon);
-            }
-        }
-    }
-
-    //================================================================================
-    // Override Methods
-    //================================================================================
-
-    /**
-     * @return an unmodifiable list of the StackPane children
-     */
-    @Override
-    public ObservableList<Node> getChildren() {
-        return FXCollections.unmodifiableObservableList(super.getChildren());
-    }
-
-    @Override
-    protected void layoutChildren() {
-        super.layoutChildren();
-
-	    if (getSize() == -1) {
-		    Node icon = getIcon();
-		    double iW = icon.prefWidth(-1);
-		    double iH = icon.prefHeight(-1);
-		    Insets padding = getPadding();
-		    double size = Math.max(padding.getLeft() + iW + padding.getRight(), padding.getTop() + iH + padding.getBottom());
-		    setSize(size);
-	    }
-    }
+	//================================================================================
+	// Properties
+	//================================================================================
+	private final String STYLE_CLASS = "mfx-icon-wrapper";
+
+	private final ObjectProperty<Node> icon = new SimpleObjectProperty<>();
+	private final MFXCircleRippleGenerator rippleGenerator = new MFXCircleRippleGenerator(this);
+
+	//================================================================================
+	// Constructors
+	//================================================================================
+	public MFXIconWrapper() {
+		initialize();
+	}
+
+	public MFXIconWrapper(Node icon, double size) {
+		initialize();
+
+		setIcon(icon);
+		setSize(size);
+	}
+
+	public MFXIconWrapper(String description, double iconSize, double wrapperSize) {
+		initialize();
+
+		setIcon(new MFXFontIcon(description, iconSize));
+		setSize(wrapperSize);
+	}
+
+	public MFXIconWrapper(String description, double iconSize, Color iconColor, double wrapperSize) {
+		initialize();
+
+		setIcon(new MFXFontIcon(description, iconSize, iconColor));
+		setSize(wrapperSize);
+	}
+
+	//================================================================================
+	// Methods
+	//================================================================================
+
+	/**
+	 * Adds a ripple generator to the icon. It is an optional.
+	 */
+	public MFXIconWrapper addRippleGenerator() {
+		if (!getChildren().contains(rippleGenerator)) {
+			super.getChildren().add(0, rippleGenerator);
+		}
+
+		return this;
+	}
+
+	/**
+	 * Adds the ripple generator to the icon by calling {@link #addRippleGenerator()}, sets its position function
+	 * to use the mouse event x and y coordinates, and adds the event filter to the icon to generate the ripples.
+	 *
+	 * @see IRippleGenerator
+	 * @see MFXCircleRippleGenerator
+	 */
+	public MFXIconWrapper defaultRippleGeneratorBehavior() {
+		addRippleGenerator();
+		rippleGenerator.setRipplePositionFunction(event -> PositionBean.of(event.getX(), event.getY()));
+		addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
+			if (event.getButton() == MouseButton.PRIMARY) {
+				rippleGenerator.generateRipple(event);
+			}
+		});
+		return this;
+	}
+
+	/**
+	 * Adds the ripple generator to the icon by calling {@link #addRippleGenerator()}, sets its position function
+	 * to the given function, and adds the event filter to the icon to generate the ripples.
+	 *
+	 * @see IRippleGenerator
+	 * @see MFXCircleRippleGenerator
+	 */
+	public MFXIconWrapper rippleGeneratorBehavior(Function<MouseEvent, PositionBean> positionFunction) {
+		addRippleGenerator();
+		rippleGenerator.setRipplePositionFunction(positionFunction);
+		addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
+			if (event.getButton() == MouseButton.PRIMARY) {
+				rippleGenerator.generateRipple(event);
+			}
+		});
+		return this;
+	}
+
+	private void initialize() {
+		getStyleClass().add(STYLE_CLASS);
+
+		setMinSize(USE_PREF_SIZE, USE_PREF_SIZE);
+		setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
+
+		icon.addListener((observable, oldValue, newValue) -> {
+			super.getChildren().remove(oldValue);
+			manageIcon(newValue);
+		});
+		size.addListener((observable, oldValue, newValue) -> setPrefSize(newValue.doubleValue(), newValue.doubleValue()));
+	}
+
+	/**
+	 * This method handles the positioning of the icon in the children list.
+	 */
+	private void manageIcon(Node icon) {
+		if (icon == null) {
+			return;
+		}
+
+		ObservableList<Node> children = super.getChildren();
+
+		if (children.isEmpty()) {
+			children.add(icon);
+			return;
+		}
+
+		if (children.contains(rippleGenerator)) {
+			if (children.size() == 1) {
+				children.add(icon);
+			} else {
+				children.set(1, icon);
+			}
+		}
+	}
+
+	//================================================================================
+	// Override Methods
+	//================================================================================
+
+	/**
+	 * @return an unmodifiable list of the StackPane children
+	 */
+	@Override
+	public ObservableList<Node> getChildren() {
+		return FXCollections.unmodifiableObservableList(super.getChildren());
+	}
+
+	@Override
+	protected void layoutChildren() {
+		super.layoutChildren();
+
+		if (getSize() == -1) {
+			Node icon = getIcon();
+			double iW = icon.prefWidth(-1);
+			double iH = icon.prefHeight(-1);
+			Insets padding = getPadding();
+			double size = Math.max(padding.getLeft() + iW + padding.getRight(), padding.getTop() + iH + padding.getBottom());
+			setSize(size);
+		}
+	}
 
 	//================================================================================
 	// Styleable Properties

Някои файлове не бяха показани, защото твърде много файлове са промени