Browse Source

Refactor, bug fix and documentation

MFXCheckbox added markSize property since now it is not a SVG but a Font character.
MFXComboBoxSkin and MFXTextFieldSkin remade line animation.

Signed-off-by: PAlex404 <alessandro.parisi406@gmail.com>
PAlex404 4 years ago
parent
commit
59d0e99e24
26 changed files with 458 additions and 133 deletions
  1. 2 2
      demo/src/main/resources/io/github/palexdev/materialfx/demo/checkboxes_demo.fxml
  2. 1 1
      demo/src/main/resources/io/github/palexdev/materialfx/demo/textfields_demo.fxml
  3. 110 46
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/CheckModel.java
  4. 52 0
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckTreeItem.java
  5. 26 5
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckTreeView.java
  6. 30 1
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXCheckbox.java
  7. 2 0
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXIconWrapper.java
  8. 30 0
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXProgressSpinner.java
  9. 2 4
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTreeItem.java
  10. 32 7
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTreeView.java
  11. 2 1
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/base/AbstractMFXTreeCell.java
  12. 7 0
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/base/AbstractMFXTreeItem.java
  13. 3 1
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/base/ICheckModel.java
  14. 28 13
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/cell/MFXCheckTreeCell.java
  15. 14 0
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/cell/MFXDateCell.java
  16. 3 4
      materialfx/src/main/java/io/github/palexdev/materialfx/controls/cell/MFXSimpleTreeCell.java
  17. 30 3
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXCheckTreeItemSkin.java
  18. 7 6
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXCheckboxSkin.java
  19. 12 10
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXComboBoxSkin.java
  20. 0 4
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXDatePickerContent.java
  21. 43 0
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXProgressSpinnerSkin.java
  22. 14 12
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTextFieldSkin.java
  23. 2 3
      materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTreeItemSkin.java
  24. 1 9
      materialfx/src/main/resources/io/github/palexdev/materialfx/css/mfx-checktreecell.css
  25. 1 1
      materialfx/src/main/resources/io/github/palexdev/materialfx/css/mfx-treecell.css
  26. 4 0
      materialfx/src/main/resources/io/github/palexdev/materialfx/css/mfx-treeview.css

+ 2 - 2
demo/src/main/resources/io/github/palexdev/materialfx/demo/checkboxes_demo.fxml

@@ -7,7 +7,7 @@
 <?import javafx.scene.paint.LinearGradient?>
 <?import javafx.scene.paint.Stop?>
 <StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
-           prefWidth="600.0" stylesheets="@css/checkboxes_demo.css" xmlns="http://javafx.com/javafx/11.0.1">
+           prefWidth="600.0" stylesheets="@css/checkboxes_demo.css" xmlns="http://javafx.com/javafx/15.0.1">
     <Label id="customLabel" alignment="CENTER" prefHeight="26.0" prefWidth="266.0" text="Checkboxes color" StackPane.alignment="TOP_CENTER">
         <StackPane.margin>
             <Insets top="20.0" />
@@ -86,7 +86,7 @@
             <Insets left="300.0" top="130.0" />
         </StackPane.margin>
     </MFXCheckbox>
-    <MFXCheckbox markType="mfx-variant9-mark" text="Variant 9">
+    <MFXCheckbox markSize="9.0" markType="mfx-variant9-mark" text="Variant 9">
         <StackPane.margin>
             <Insets top="195.0" />
         </StackPane.margin>

+ 1 - 1
demo/src/main/resources/io/github/palexdev/materialfx/demo/textfields_demo.fxml

@@ -39,7 +39,7 @@
          <Insets left="150.0" top="180.0" />
       </StackPane.margin>
    </MFXTextField>
-   <MFXCheckbox fx:id="checkbox" checkedColor="#00e240" markType="VARIANT9" text="CheckBox Validation" StackPane.alignment="BOTTOM_LEFT">
+   <MFXCheckbox fx:id="checkbox" checkedColor="#00e240" markType="mfx-variant9-mark" text="CheckBox Validation" StackPane.alignment="BOTTOM_LEFT">
       <StackPane.margin>
          <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
       </StackPane.margin>

+ 110 - 46
materialfx/src/main/java/io/github/palexdev/materialfx/controls/CheckModel.java

@@ -14,9 +14,26 @@ import java.util.stream.Collectors;
 
 import static io.github.palexdev.materialfx.controls.MFXCheckTreeItem.CheckTreeItemEvent;
 
+/**
+ * Concrete implementation of the {@code ICheckModel} class.
+ * <p>
+ * This provides common methods for items check. Also, since it extends SelectionModel it also provides
+ * all the methods for items selection.
+ * <p>
+ * The check should be handled internally only. This is because the mechanism is kind of tricky.
+ * If you take a look at the MFXCheckTreeItem's skin, {@link io.github.palexdev.materialfx.skins.MFXCheckTreeItemSkin},
+ * you can see that when the checkbox is fired, a CHECK_EVENT is fired and "travels" up to the root. Each item then calls
+ * {@link #check(MFXCheckTreeItem, CheckTreeItemEvent)}.
+ */
 public class CheckModel<T> extends SelectionModel<T> implements ICheckModel<T> {
+    //================================================================================
+    // Properties
+    //================================================================================
     private final ListProperty<MFXCheckTreeItem<T>> checkedItems = new SimpleListProperty<>(FXCollections.observableArrayList());
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public CheckModel() {
         super();
         checkedItems.addListener((ListChangeListener<MFXCheckTreeItem<T>>) change -> {
@@ -32,6 +49,86 @@ public class CheckModel<T> extends SelectionModel<T> implements ICheckModel<T> {
         });
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
+
+    /**
+     * This method is called when the event argument passed to {@link #check(MFXCheckTreeItem, CheckTreeItemEvent)}
+     * is null. It is used for example when you want the tree to start with one or more checked items like this:
+     * <pre>
+     *     {@code
+     *         MFXCheckTreeItem<String> root = new MFXCheckTreeItem<>("ROOT");
+     *         MFXCheckTreeItem<String> i1 = new MFXCheckTreeItem<>("I1");
+     *         MFXCheckTreeItem<String> i1a = new MFXCheckTreeItem<>("I1A");
+     *         MFXCheckTreeItem<String> i2 = new MFXCheckTreeItem<>("I1B");
+     *
+     *         i1.setChecked(true);
+     *         i1a.setChecked(true);
+     *         i2.setChecked(true);
+     *     }
+     * </pre>
+     * @see MFXCheckTreeItem
+     * @param item the item to check
+     */
+    private void check(MFXCheckTreeItem<T> item) {
+        if (item.isChecked()) {
+            checkedItems.remove(item);
+        } else {
+            checkedItems.add(item);
+        }
+    }
+
+    /**
+     * Adds all the passed items to the checkedItems list.
+     */
+    private void checkAll(List<MFXCheckTreeItem<T>> items) {
+        checkedItems.addAll(items);
+    }
+
+    /**
+     * Removes all the passed items from the checkedItems list.
+     */
+    private void uncheckAll(List<MFXCheckTreeItem<T>> items) {
+        checkedItems.removeAll(items);
+    }
+
+    /**
+     * Counts all the checked children of the passed item.
+     */
+    private int checkedChildren(MFXCheckTreeItem<T> item) {
+        int cnt = 0;
+        for (AbstractMFXTreeItem<T> treeItem : item.getItems()) {
+            MFXCheckTreeItem<T> cItem = (MFXCheckTreeItem<T>) treeItem;
+            if (cItem.isChecked()) {
+                cnt++;
+            }
+        }
+        return cnt;
+    }
+
+    /**
+     * Counts all the indeterminate children of the passed item.
+     */
+    private int indeterminateChildren(MFXCheckTreeItem<T> item) {
+        int cnt = 0;
+        for (AbstractMFXTreeItem<T> treeItem : item.getItems()) {
+            MFXCheckTreeItem<T> cItem = (MFXCheckTreeItem<T>) treeItem;
+            if (cItem.isIndeterminate()) {
+                cnt++;
+            }
+        }
+        return cnt;
+    }
+
+    //================================================================================
+    // Override Methods
+    //================================================================================
+
+    /**
+     * If you set some item to be checked before the tree is laid out then it's needed
+     * to scan the tree and add all the checked items to the list.
+     */
     @Override
     public void scanTree(MFXCheckTreeItem<T> item) {
         clearChecked();
@@ -40,6 +137,13 @@ public class CheckModel<T> extends SelectionModel<T> implements ICheckModel<T> {
         });
     }
 
+    /**
+     * This method is called by {@link io.github.palexdev.materialfx.skins.MFXCheckTreeItemSkin} when
+     * the checkbox is fired. We need the event as a parameter to distinguish between the item
+     * on which the CHECK_EVENT was fired and the parent items.
+     * <p>
+     * If the event is null we call the other {@link #check(MFXCheckTreeItem)} method.
+     */
     @Override
     public void check(MFXCheckTreeItem<T> item, CheckTreeItemEvent<?> event) {
         if (event == null) {
@@ -73,44 +177,9 @@ public class CheckModel<T> extends SelectionModel<T> implements ICheckModel<T> {
         }
     }
 
-    private void check(MFXCheckTreeItem<T> item) {
-        if (item.isChecked()) {
-            checkedItems.remove(item);
-        } else {
-            checkedItems.add(item);
-        }
-    }
-
-    private void checkAll(List<MFXCheckTreeItem<T>> items) {
-        checkedItems.addAll(items);
-    }
-
-    private void uncheckAll(List<MFXCheckTreeItem<T>> items) {
-        checkedItems.removeAll(items);
-    }
-
-    private int checkedChildren(MFXCheckTreeItem<T> item) {
-        int cnt = 0;
-        for (AbstractMFXTreeItem<T> treeItem : item.getItems()) {
-            MFXCheckTreeItem<T> cItem = (MFXCheckTreeItem<T>) treeItem;
-            if (cItem.isChecked()) {
-                cnt++;
-            }
-        }
-        return cnt;
-    }
-
-    private int indeterminateChildren(MFXCheckTreeItem<T> item) {
-        int cnt = 0;
-        for (AbstractMFXTreeItem<T> treeItem : item.getItems()) {
-            MFXCheckTreeItem<T> cItem = (MFXCheckTreeItem<T>) treeItem;
-            if (cItem.isIndeterminate()) {
-                cnt++;
-            }
-        }
-        return cnt;
-    }
-
+    /**
+     * Resets every item in the list to checked false and then clears the list.
+     */
     @Override
     public void clearChecked() {
         if (checkedItems.isEmpty()) {
@@ -121,14 +190,9 @@ public class CheckModel<T> extends SelectionModel<T> implements ICheckModel<T> {
         checkedItems.clear();
     }
 
-    @Override
-    public MFXCheckTreeItem<T> getCheckedItem() {
-        if (checkedItems.isEmpty()) {
-            return null;
-        }
-        return checkedItems.get(0);
-    }
-
+    /**
+     * @return the ListProperty which contains all the checked items.
+     */
     @Override
     public ListProperty<MFXCheckTreeItem<T>> getCheckedItems() {
         return this.checkedItems;

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

@@ -15,13 +15,27 @@ import javafx.util.Callback;
 
 import java.lang.ref.WeakReference;
 
+/**
+ * Simple implementation of a tree item with a checkbox.
+ * <p>
+ * The default associated {@link Skin} is {@link MFXCheckTreeItemSkin<T>}.
+ * @see MFXCheckTreeView
+ * @see ICheckModel
+ * @param <T> The type of the data within TreeItem.
+ */
 public class MFXCheckTreeItem<T> extends MFXTreeItem<T> {
+    //================================================================================
+    // Properties
+    //================================================================================
     private final String STYLE_CLASS = "mfx-check-tree-item";
     private final String STYLESHEET = MFXResourcesLoader.load("css/mfx-treeitem.css").toString();
 
     private final BooleanProperty checked = new SimpleBooleanProperty(false);
     private final BooleanProperty indeterminate = new SimpleBooleanProperty(false);
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXCheckTreeItem(T data) {
         super(data);
         initialize();
@@ -32,6 +46,16 @@ public class MFXCheckTreeItem<T> extends MFXTreeItem<T> {
         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 CheckModel {@link CheckModel#scanTree(MFXCheckTreeItem)} )} method.
+     */
     private void initialize() {
         getStyleClass().add(STYLE_CLASS);
 
@@ -67,16 +91,29 @@ public class MFXCheckTreeItem<T> extends MFXTreeItem<T> {
         this.indeterminate.set(indeterminate);
     }
 
+    //================================================================================
+    // Override Methods
+    //================================================================================
+
+    /**
+     * Overridden to return the ICheckModel instance of the MFXCheckTreeView.
+     */
     @Override
     public ICheckModel<T> getSelectionModel() {
         return (ICheckModel<T>) super.getSelectionModel();
     }
 
+    /**
+     * Overridden to use {@link MFXCheckTreeCell}s.
+     */
     @Override
     protected void defaultCellFactory() {
         super.cellFactory.set(cell -> new MFXCheckTreeCell<>(this));
     }
 
+    /**
+     * Overridden to use {@link MFXCheckTreeItemSkin}.
+     */
     @Override
     protected Skin<?> createDefaultSkin() {
         return new MFXCheckTreeItemSkin<>(this);
@@ -87,6 +124,21 @@ public class MFXCheckTreeItem<T> extends MFXTreeItem<T> {
         return STYLESHEET;
     }
 
+    //================================================================================
+    // Events Class
+    //================================================================================
+
+    /**
+     * 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;
 

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

@@ -1,19 +1,40 @@
 package io.github.palexdev.materialfx.controls;
 
+/**
+ * This is the container for a tree made of MFXCheckTreeItems.
+ * <p>
+ * Note: this could also work with other item classes since the CheckModel extends SelectionModel,
+ * but of course it is not recommended to do so.
+ * @param <T> The type of the data within the items.
+ */
 public class MFXCheckTreeView<T> extends MFXTreeView<T> {
-
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXCheckTreeView(MFXTreeItem<T> root) {
         super(root);
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
+    public CheckModel<T> getCheckModel() {
+        return (CheckModel<T>) super.getSelectionModel();
+    }
+
+    //================================================================================
+    // Override Methods
+    //================================================================================
+
+    /**
+     * Overridden method to install a CheckModel.
+     * <p>
+     * By default it is set to allow multiple selection.
+     */
     @Override
     protected void installSelectionModel() {
         CheckModel<T> checkModel = new CheckModel<>();
         checkModel.setAllowsMultipleSelection(true);
         setSelectionModel(checkModel);
     }
-
-    public CheckModel<T> getCheckModel() {
-        return (CheckModel<T>) super.getSelectionModel();
-    }
 }

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

@@ -81,6 +81,16 @@ public class MFXCheckbox extends CheckBox {
             "mfx-modena-mark"
     );
 
+    /**
+     * Specifies the size of the mark.
+     */
+    private final StyleableDoubleProperty markSize = new SimpleStyleableDoubleProperty(
+            StyleableProperties.MARK_SIZE,
+            this,
+            "markSize",
+            12.0
+    );
+
     public Paint getCheckedColor() {
         return checkedColor.get();
     }
@@ -117,6 +127,18 @@ public class MFXCheckbox extends CheckBox {
         this.markType.set(markType);
     }
 
+    public double getMarkSize() {
+        return markSize.get();
+    }
+
+    public StyleableDoubleProperty markSizeProperty() {
+        return markSize;
+    }
+
+    public void setMarkSize(double markSize) {
+        this.markSize.set(markSize);
+    }
+
     //================================================================================
     // CssMetaData
     //================================================================================
@@ -144,8 +166,15 @@ public class MFXCheckbox extends CheckBox {
                         "mfx-modena-mark"
                 );
 
+        private static final CssMetaData<MFXCheckbox, Number> MARK_SIZE =
+                FACTORY.createSizeCssMetaData(
+                        "-mfx-mark-size",
+                        MFXCheckbox::markSizeProperty,
+                        12
+                );
+
         static {
-            cssMetaDataList = List.of(CHECKED_COLOR, UNCHECKED_COLOR, MARK_TYPE);
+            cssMetaDataList = List.of(CHECKED_COLOR, UNCHECKED_COLOR, MARK_TYPE, MARK_SIZE);
         }
     }
 

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

@@ -72,6 +72,8 @@ public class MFXIconWrapper extends StackPane {
     public void setIcon(Node node) {
         if (getChildren().size() > 1) {
             super.getChildren().set(1, node);
+        } else if (!getChildren().isEmpty() && (getChildren().get(0) instanceof RippleGenerator)){
+            super.getChildren().add(0, node);
         } else {
             super.getChildren().set(0, node);
         }

+ 30 - 0
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXProgressSpinner.java

@@ -9,11 +9,22 @@ import javafx.scene.layout.Region;
 
 import java.util.List;
 
+/**
+ * Implementation of a spinning {@code ProgressIndicator}.
+ * <p>
+ * Extends {@link ProgressIndicator}
+ */
 public class MFXProgressSpinner extends ProgressIndicator {
+    //================================================================================
+    // Properties
+    //================================================================================
     private static final StyleablePropertyFactory<MFXProgressSpinner> FACTORY = new StyleablePropertyFactory<>(ProgressIndicator.getClassCssMetaData());
     private final String STYLE_CLASS = "mfx-spinner";
     private final String STYLESHEET = MFXResourcesLoader.load("css/mfx-spinner.css").toString();
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXProgressSpinner() {
         this(-1);
     }
@@ -23,10 +34,20 @@ public class MFXProgressSpinner extends ProgressIndicator {
         initialize();
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
     private void initialize() {
         getStyleClass().add(STYLE_CLASS);
     }
 
+    //================================================================================
+    // Styleable Properties
+    //================================================================================
+
+    /**
+     * Specifies the radius of the spinner.
+     */
     private final StyleableDoubleProperty radius = new SimpleStyleableDoubleProperty(
             StyleableProperties.RADIUS,
             this,
@@ -34,6 +55,9 @@ public class MFXProgressSpinner extends ProgressIndicator {
             Region.USE_COMPUTED_SIZE
     );
 
+    /**
+     * Specifies the starting angle of the animation.
+     */
     private final StyleableDoubleProperty startingAngle = new SimpleStyleableDoubleProperty(
             StyleableProperties.STARTING_ANGLE,
             this,
@@ -65,6 +89,9 @@ public class MFXProgressSpinner extends ProgressIndicator {
         this.startingAngle.set(startingAngle);
     }
 
+    //================================================================================
+    // CssMetaData
+    //================================================================================
     private static class StyleableProperties {
         private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
 
@@ -91,6 +118,9 @@ public class MFXProgressSpinner extends ProgressIndicator {
         return StyleableProperties.cssMetaDataList;
     }
 
+    //================================================================================
+    // Override Methods
+    //================================================================================
     @Override
     protected Skin<?> createDefaultSkin() {
         return new MFXProgressSpinnerSkin(this);

+ 2 - 4
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTreeItem.java

@@ -65,15 +65,13 @@ public class MFXTreeItem<T> extends AbstractMFXTreeItem<T> {
     // Methods
     //================================================================================
 
-    //TODO change
     /**
      * Sets the style class to "mfx-tree-view".
      * <p>
      * Adds a listener to the items list to update the added/removed item parent accordingly.
      * <p>
-     * Adds a listener to {@link #selectedProperty()} the treeView property allowing item selection before the Scene is shown.
-     * If the treeView property is null and the selectionModel can't be retrieved we add a listener to the treeView property
-     * so that when it is not null anymore we can update the selection state of the items calling {@link ISelectionModel#scanTree(AbstractMFXTreeItem)}.
+     * Adds a listener to {@link #selectedProperty()} and the {@link #treeViewProperty()} allowing item selection before the Scene is shown
+     * by calling the SelectionModel {@link SelectionModel#scanTree(AbstractMFXTreeItem)} method.
      */
     private void initialize() {
         getStyleClass().add(STYLE_CLASS);

+ 32 - 7
materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTreeView.java

@@ -7,15 +7,24 @@ import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.geometry.Insets;
 
+/**
+ * This is the container for a tree made of AbstractMFXTreeItems.
+ * @param <T> The type of the data within the items.
+ */
 public class MFXTreeView<T> extends MFXScrollPane {
+    //================================================================================
+    // Properties
+    //================================================================================
     private final String STYLE_CLASS = "mfx-tree-view";
     private final String STYLESHEET = MFXResourcesLoader.load("css/mfx-treeview.css").toString();
 
     private final ObjectProperty<AbstractMFXTreeItem<T>> root = new SimpleObjectProperty<>(null);
     private final ObjectProperty<ISelectionModel<T>> selectionModel = new SimpleObjectProperty<>(null);
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXTreeView(MFXTreeItem<T> root) {
-        setStyle("-fx-border-color: gold");
         installSelectionModel();
 
         root.setTreeView(this);
@@ -24,9 +33,17 @@ public class MFXTreeView<T> extends MFXScrollPane {
         initialize();
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
+
+    /**
+     * Sets the style class, sets the pref size, adds smooth vertical scroll and
+     * binds the root prefWidth to this control width property (minus 10).
+     */
     protected void initialize() {
         getStyleClass().add(STYLE_CLASS);
-        setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE); // TODO remove
+        setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
         setPrefSize(250, 500);
         setPadding(new Insets(3));
         MFXScrollPane.smoothVScrolling(this);
@@ -34,17 +51,17 @@ public class MFXTreeView<T> extends MFXScrollPane {
         getRoot().prefWidthProperty().bind(widthProperty().subtract(10));
     }
 
+    /**
+     * Installs the default selection model to use for the tree.
+     * <p>
+     * By default it is set to allow multiple selection.
+     */
     protected void installSelectionModel() {
         ISelectionModel<T> selectionModel = new SelectionModel<>();
         selectionModel.setAllowsMultipleSelection(true);
         setSelectionModel(selectionModel);
     }
 
-    @Override
-    public String getUserAgentStylesheet() {
-        return STYLESHEET;
-    }
-
     public AbstractMFXTreeItem<T> getRoot() {
         return root.get();
     }
@@ -69,4 +86,12 @@ public class MFXTreeView<T> extends MFXScrollPane {
         this.selectionModel.set(selectionModel);
     }
 
+    //================================================================================
+    // Override Methods
+    //================================================================================
+    @Override
+    public String getUserAgentStylesheet() {
+        return STYLESHEET;
+    }
+
 }

+ 2 - 1
materialfx/src/main/java/io/github/palexdev/materialfx/controls/base/AbstractMFXTreeCell.java

@@ -14,7 +14,7 @@ import javafx.scene.layout.HBox;
  * Specifies properties and methods that should be common to all cells.
  * <p>
  * It's common for TreeViews to display the data in an horizontal container and that's why
- * this class expends HBox rather than Control and define its skin.
+ * this class extends HBox rather than Control and define its skin.
  * <p>
  * To build a cell the item data should be sufficient however the constructors have been
  * refactored to pass th AbstractMFXTreeItem as parameter because to implement cell selection
@@ -22,6 +22,7 @@ import javafx.scene.layout.HBox;
  * It's kinda tricky because one needs to select the item but if you select the item and update its background
  * accordingly you set the background color of the entire container not the item's cell. So we
  * select the item in the model but in the view the cell appears selected.
+ * The same concept applies to {@code MFXCheckTreeCell}s.
  * <p>
  * Also, note that to build a cell the height must be fixed for layout reasons, by default it's 27.
  * When the cell is created the {@link #render(T)} method is called.

+ 7 - 0
materialfx/src/main/java/io/github/palexdev/materialfx/controls/base/AbstractMFXTreeItem.java

@@ -166,6 +166,13 @@ public abstract class AbstractMFXTreeItem<T> extends Control {
         return parentItems.get(index - 1);
     }
 
+    /**
+     * @return if this item is leaf or not.
+     */
+    public boolean isLeaf() {
+        return items.isEmpty();
+    }
+
     /**
      * Retrieves the instance of the TreeView which contains the tree.
      * <p>

+ 3 - 1
materialfx/src/main/java/io/github/palexdev/materialfx/controls/base/ICheckModel.java

@@ -5,10 +5,12 @@ import javafx.beans.property.ListProperty;
 
 import static io.github.palexdev.materialfx.controls.MFXCheckTreeItem.CheckTreeItemEvent;
 
+/**
+ * Public API used by any MFXCheckTreeView.
+ */
 public interface ICheckModel<T> extends ISelectionModel<T> {
     void scanTree(MFXCheckTreeItem<T> item);
     void check(MFXCheckTreeItem<T> item, CheckTreeItemEvent<?> event);
     void clearChecked();
-    MFXCheckTreeItem<T> getCheckedItem();
     ListProperty<MFXCheckTreeItem<T>> getCheckedItems();
 }

+ 28 - 13
materialfx/src/main/java/io/github/palexdev/materialfx/controls/cell/MFXCheckTreeCell.java

@@ -3,24 +3,30 @@ package io.github.palexdev.materialfx.controls.cell;
 import io.github.palexdev.materialfx.MFXResourcesLoader;
 import io.github.palexdev.materialfx.controls.MFXCheckTreeItem;
 import io.github.palexdev.materialfx.controls.MFXCheckbox;
-import io.github.palexdev.materialfx.effects.RippleGenerator;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.SimpleBooleanProperty;
 import javafx.css.PseudoClass;
-import javafx.scene.control.CheckBox;
-import javafx.scene.paint.Color;
 
-// TODO change to MFXCheckbox, after refactor
+/**
+ * Implementation of a MFXSimpleTreeCell with a checkbox for usage in MFXCheckTreeViews.
+ * @param <T>
+ */
 public class MFXCheckTreeCell<T> extends MFXSimpleTreeCell<T> {
+    //================================================================================
+    // Properties
+    //================================================================================
     private final String STYLE_CLASS = "mfx-check-tree-cell";
     private final String STYLESHEET = MFXResourcesLoader.load("css/mfx-checktreecell.css").toString();
-    private final CheckBox checkbox;
+    private final MFXCheckbox checkbox;
 
     private static final PseudoClass CHECKED_PSEUDO_CLASS = PseudoClass.getPseudoClass("checked");
     private static final PseudoClass INDETERMINATE_PSEUDO_CLASS = PseudoClass.getPseudoClass("indeterminate");
     private final BooleanProperty checked = new SimpleBooleanProperty(false);
     private final BooleanProperty indeterminate = new SimpleBooleanProperty(false);
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXCheckTreeCell(MFXCheckTreeItem<T> item) {
         super(item);
         checkbox = new MFXCheckbox("");
@@ -35,6 +41,14 @@ public class MFXCheckTreeCell<T> extends MFXSimpleTreeCell<T> {
         initialize(item);
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
+
+    /**
+     * Sets the cell style class, sets the fixed cells size to 32, adds bindings for
+     * checked and indeterminate properties.
+     */
     private void initialize(MFXCheckTreeItem<T> item) {
         getStyleClass().add(STYLE_CLASS);
         setFixedCellSize(32);
@@ -42,23 +56,24 @@ public class MFXCheckTreeCell<T> extends MFXSimpleTreeCell<T> {
         addListeners();
         checked.bind(item.checkedProperty());
         indeterminate.bind(item.indeterminateProperty());
+        checkbox.setMarkType("mfx-variant3-mark");
+        checkbox.setMarkSize(8);
     }
 
+    /**
+     * Adds listeners for checked and indeterminate properties.
+     */
     private void addListeners() {
         checked.addListener(invalidate -> pseudoClassStateChanged(CHECKED_PSEUDO_CLASS, checked.get()));
         checked.addListener((observable, oldValue, newValue) -> checkbox.setSelected(newValue));
         indeterminate.addListener(invalidate -> pseudoClassStateChanged(INDETERMINATE_PSEUDO_CLASS, indeterminate.get()));
         indeterminate.addListener((observable, oldValue, newValue) -> checkbox.setIndeterminate(newValue));
-
-        checkbox.skinProperty().addListener((observable, oldValue, newValue) -> {
-            if (newValue != null) {
-                RippleGenerator rippleGenerator = (RippleGenerator) checkbox.lookup(".ripple-generator");
-                rippleGenerator.setRippleColor(Color.FIREBRICK);
-            }
-        });
     }
 
-    public CheckBox getCheckbox() {
+    /**
+     * @return this cell's checkbox instance
+     */
+    public MFXCheckbox getCheckbox() {
         return checkbox;
     }
 

+ 14 - 0
materialfx/src/main/java/io/github/palexdev/materialfx/controls/cell/MFXDateCell.java

@@ -17,6 +17,9 @@ import javafx.scene.shape.Circle;
  * current dates. Includes ripple effects.
  */
 public class MFXDateCell extends DateCell {
+    //================================================================================
+    // Properties
+    //================================================================================
     private final String STYLE_CLASS = "mfx-date-cell";
 
     private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selectedDate");
@@ -29,6 +32,9 @@ public class MFXDateCell extends DateCell {
 
     private boolean drawGraphic = false;
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXDateCell() {
         initialize();
     }
@@ -44,12 +50,20 @@ public class MFXDateCell extends DateCell {
         initialize();
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
     private void initialize() {
         rippleGenerator.setRippleColor(Color.rgb(220, 220, 220, 0.6));
         getStyleClass().setAll(STYLE_CLASS);
         addListeners();
     }
 
+    /**
+     * Adds listeners to selected and current date properties.
+     * <p>
+     * Adds event handler for ripple generator.
+     */
     private void addListeners() {
         selectedDate.addListener(invalidate -> pseudoClassStateChanged(SELECTED_PSEUDO_CLASS, selectedDate.get()));
         current.addListener(invalidate -> pseudoClassStateChanged(CURRENT_DAY_PSEUDO_CLASS, current.get()));

+ 3 - 4
materialfx/src/main/java/io/github/palexdev/materialfx/controls/cell/MFXSimpleTreeCell.java

@@ -43,8 +43,7 @@ public class MFXSimpleTreeCell<T> extends AbstractMFXTreeCell<T> {
     //================================================================================
 
     /**
-     * Override of the AbstractMFXTreeCell initialize method to set the cell style class,
-     * build and set the default disclosure node {@link MFXSimpleTreeCell#defaultDisclosureNode()}
+     * Sets the cell style class,build and set the default disclosure node {@link MFXSimpleTreeCell#defaultDisclosureNode()}
      * and adds a listener to the disclosure node property in case the user changes it.
      */
     private void initialize() {
@@ -67,7 +66,6 @@ public class MFXSimpleTreeCell<T> extends AbstractMFXTreeCell<T> {
     protected void defaultDisclosureNode() {
         MFXIconWrapper disclosureNode = new MFXIconWrapper().addRippleGenerator();
         disclosureNode.setSize(22);
-        disclosureNode.setStyle("-fx-border-color: gold");
         disclosureNode.getStyleClass().setAll("disclosure-node");
         NodeUtils.makeRegionCircular(disclosureNode, 9.5);
 
@@ -100,6 +98,7 @@ public class MFXSimpleTreeCell<T> extends AbstractMFXTreeCell<T> {
 
     /**
      * {@inheritDoc}
+     * <p>
      * If the data is a Node then it is added to the box.
      * <p>
      * If it is not a Node than a label is created, the label has style class: "data-label",
@@ -121,7 +120,7 @@ public class MFXSimpleTreeCell<T> extends AbstractMFXTreeCell<T> {
      * {@inheritDoc}
      * Updates the cell when needed. When the items list changes adds or removes the disclosure node's
      * icon accordingly. Also checks if the item has the {@link MFXTreeItem#startExpandedProperty()} set to true,
-     * in this case the disclosure node must be rotated by 90°
+     * in this case the disclosure node must be rotated by 90°.
      */
     @Override
     public void updateCell(MFXTreeItem<T> item) {

+ 30 - 3
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXCheckTreeItemSkin.java

@@ -4,25 +4,52 @@ import io.github.palexdev.materialfx.controls.MFXCheckTreeItem;
 import io.github.palexdev.materialfx.controls.base.AbstractMFXTreeCell;
 import io.github.palexdev.materialfx.controls.cell.MFXCheckTreeCell;
 import javafx.scene.control.CheckBox;
-import javafx.scene.input.MouseEvent;
 
 import static io.github.palexdev.materialfx.controls.MFXCheckTreeItem.CheckTreeItemEvent;
 
+/**
+ * This is the implementation of the {@code Skin} associated with every {@link MFXCheckTreeItemSkin}.
+ * @see MFXCheckTreeItem
+ * @see io.github.palexdev.materialfx.controls.CheckModel
+ */
 public class MFXCheckTreeItemSkin<T> extends MFXTreeItemSkin<T> {
-
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXCheckTreeItemSkin(MFXCheckTreeItem<T> item) {
         super(item);
 
+        setListeners();
+    }
+
+    //================================================================================
+    // Methods
+    //================================================================================
+
+    /**
+     * Adds a listener for handling CHECK_EVENTs and call {@link io.github.palexdev.materialfx.controls.CheckModel#check(MFXCheckTreeItem, CheckTreeItemEvent)}.
+     */
+    private void setListeners() {
+        MFXCheckTreeItem<T> item = (MFXCheckTreeItem<T>) getSkinnable();
+
         item.addEventHandler(CheckTreeItemEvent.CHECK_EVENT, event -> item.getSelectionModel().check(item, event));
     }
 
+    //================================================================================
+    // Override Methods
+    //================================================================================
+
+    /**
+     * Overridden method to create a MFXCheckTreeCell and fire a CHECK_EVENT
+     * on checkbox action.
+     */
     @Override
     protected AbstractMFXTreeCell<T> createCell() {
         MFXCheckTreeItem<T> item = (MFXCheckTreeItem<T>) getSkinnable();
 
         MFXCheckTreeCell<T> cell = (MFXCheckTreeCell<T>) super.createCell();
         CheckBox checkbox = cell.getCheckbox();
-        checkbox.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
+        checkbox.setOnAction(event -> {
             item.fireEvent(new CheckTreeItemEvent<>(CheckTreeItemEvent.CHECK_EVENT, item));
             event.consume();
         });

+ 7 - 6
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXCheckboxSkin.java

@@ -13,6 +13,7 @@ import javafx.scene.control.SkinBase;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.*;
 import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
 import javafx.util.Duration;
 
 /**
@@ -50,7 +51,7 @@ public class MFXCheckboxSkin extends SkinBase<MFXCheckbox> {
         rippleGenerator.setAnimateBackground(false);
 
         // Contains the mark
-        MFXFontIcon icon = new MFXFontIcon(checkbox.getMarkType(), 12, Color.WHITE);
+        MFXFontIcon icon = new MFXFontIcon(checkbox.getMarkType(), checkbox.getMarkSize(), Color.WHITE);
         icon.getStyleClass().add("mark");
         box = new MFXIconWrapper(icon, boxSize);
         box.getStyleClass().add("box");
@@ -95,6 +96,9 @@ public class MFXCheckboxSkin extends SkinBase<MFXCheckbox> {
                 (observable, oldValue, newValue) -> updateMarkType()
         );
 
+        checkBox.markSizeProperty().addListener(
+                (observable, oldValue, newValue) -> ((MFXFontIcon) box.getIcon()).setFont(Font.font(newValue.doubleValue())));
+
         checkBox.selectedProperty().addListener(
                 (observable, oldValue, newValue) -> updateColors()
         );
@@ -114,7 +118,7 @@ public class MFXCheckboxSkin extends SkinBase<MFXCheckbox> {
         /* Listener on control but if the coordinates of the event are greater than then ripple container size
          * then the center of the ripple is set to the width and/or height of container
          */
-        checkBox.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
+        checkBox.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
             if (!NodeUtils.inHierarchy(event.getPickResult().getIntersectedNode(), checkBox)) {
                 return;
             }
@@ -179,10 +183,7 @@ public class MFXCheckboxSkin extends SkinBase<MFXCheckbox> {
     private void updateMarkType() {
         MFXCheckbox checkbox = getSkinnable();
 
-        MFXFontIcon icon = new MFXFontIcon(checkbox.getMarkType(), 12, Color.TRANSPARENT);
-        if (icon.getDescription().equals("mfx-variant9-mark")) {
-            icon.setSize(9);
-        }
+        MFXFontIcon icon = new MFXFontIcon(checkbox.getMarkType(), checkbox.getMarkSize(), Color.TRANSPARENT);
         box.setIcon(icon);
     }
 

+ 12 - 10
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXComboBoxSkin.java

@@ -2,9 +2,10 @@ package io.github.palexdev.materialfx.skins;
 
 import io.github.palexdev.materialfx.controls.MFXComboBox;
 import io.github.palexdev.materialfx.controls.MFXIconWrapper;
+import io.github.palexdev.materialfx.controls.factories.MFXAnimationFactory;
 import io.github.palexdev.materialfx.font.MFXFontIcon;
 import io.github.palexdev.materialfx.validation.MFXDialogValidator;
-import javafx.animation.FadeTransition;
+import javafx.animation.ScaleTransition;
 import javafx.scene.control.Label;
 import javafx.scene.control.skin.ComboBoxListViewSkin;
 import javafx.scene.input.MouseEvent;
@@ -43,7 +44,7 @@ public class MFXComboBoxSkin<T> extends ComboBoxListViewSkin<T> {
         focusLine.setStroke(comboBox.getLineColor());
         focusLine.setStrokeWidth(comboBox.getLineStrokeWidth());
         focusLine.setSmooth(true);
-        focusLine.setOpacity(0.0);
+        focusLine.setScaleX(0.0);
 
         line.endXProperty().bind(comboBox.widthProperty());
         focusLine.endXProperty().bind(comboBox.widthProperty());
@@ -112,9 +113,9 @@ public class MFXComboBoxSkin<T> extends ComboBoxListViewSkin<T> {
             }
 
             if (newValue) {
-                focusLine.setOpacity(1.0);
+                focusLine.setScaleX(1.0);
             } else {
-                focusLine.setOpacity(0.0);
+                focusLine.setScaleX(0.0);
             }
         });
 
@@ -142,15 +143,16 @@ public class MFXComboBoxSkin<T> extends ComboBoxListViewSkin<T> {
      * Builds and play the lines animation if {@code animateLines} is true.
      */
     private void buildAndPlayAnimation(boolean focused) {
-        FadeTransition fadeTransition = new FadeTransition(Duration.millis(200), focusLine);
+        ScaleTransition scaleTransition = new ScaleTransition(Duration.millis(400), focusLine);
         if (focused) {
-            fadeTransition.setFromValue(0.0);
-            fadeTransition.setToValue(1.0);
+            scaleTransition.setFromX(0.0);
+            scaleTransition.setToX(1.0);
         } else {
-            fadeTransition.setFromValue(1.0);
-            fadeTransition.setToValue(0.0);
+            scaleTransition.setFromX(1.0);
+            scaleTransition.setToX(0.0);
         }
-        fadeTransition.play();
+        scaleTransition.setInterpolator(MFXAnimationFactory.getInterpolator());
+        scaleTransition.play();
     }
 
     //================================================================================

+ 0 - 4
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXDatePickerContent.java

@@ -126,7 +126,6 @@ public class MFXDatePickerContent extends VBox {
     public MFXDatePickerContent(LocalDate localDate, DateTimeFormatter dateTimeFormatter) {
         getStyleClass().add(STYLE_CLASS);
         getStylesheets().setAll(STYLESHEET);
-        //setStyle("-fx-border-color: red");
         setPrefSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
         setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
         setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
@@ -148,7 +147,6 @@ public class MFXDatePickerContent extends VBox {
 
         holder = new StackPane(buildCalendar(), buildScroll());
         holder.getStyleClass().add("holder");
-        //holder.setStyle("-fx-border-color: blue");
         getChildren().add(holder);
 
         initialize();
@@ -607,7 +605,6 @@ public class MFXDatePickerContent extends VBox {
         calendar = new GridPane();
         calendar.getStyleClass().add("calendar");
         calendar.setVgap(10);
-        //calendar.setStyle("-fx-border-color: red");
 
         return calendar;
     }
@@ -621,7 +618,6 @@ public class MFXDatePickerContent extends VBox {
         years.setPadding(DEFAULT_INSETS);
         years.setHgap(10);
         years.setVgap(10);
-        //years.setStyle("-fx-border-color: red");
 
         return years;
     }

+ 43 - 0
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXProgressSpinnerSkin.java

@@ -22,7 +22,13 @@ import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+/**
+ *  This is the implementation of the {@code Skin} associated with every {@code MFXProgressSpinner}.
+ */
 public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
+    //================================================================================
+    // Properties
+    //================================================================================
     private boolean isValid = false;
     private boolean wasIndeterminate = false;
     private double arcLength = -1;
@@ -40,6 +46,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
 
     private Timeline timeline;
 
+    //================================================================================
+    // Constructors
+    //================================================================================
     public MFXProgressSpinnerSkin(MFXProgressSpinner spinner) {
         super(spinner);
 
@@ -80,6 +89,13 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         setListeners();
     }
 
+    //================================================================================
+    // Methods
+    //================================================================================
+
+    /**
+     * Adds listeners to: indeterminate, progress, visible, parent and scene properties.
+     */
     private void setListeners() {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -90,6 +106,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         spinner.sceneProperty().addListener((observable, oldValue, newValue) -> updateAnimation());
     }
 
+    /**
+     * Updates the progress.
+     */
     protected void updateProgress() {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -101,6 +120,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         wasIndeterminate = isIndeterminate;
     }
 
+    /**
+     * Resets the spinner animation.
+     */
     private void reset() {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -116,6 +138,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         }
     }
 
+    /**
+     * Clears the animation.
+     */
     private void clearAnimation() {
         if (timeline != null) {
             timeline.stop();
@@ -124,6 +149,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         }
     }
 
+    /**
+     * Updates the animation.
+     */
     private void updateAnimation() {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -137,6 +165,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         }
     }
 
+    /**
+     * Creates the animation.
+     */
     private void createTransition() {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -169,6 +200,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         timeline.playFromStart();
     }
 
+    /**
+     * Pauses the animation
+     */
     private void pauseTimeline(boolean pause) {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -184,6 +218,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         }
     }
 
+    /**
+     * Creates the needed key frames for the animation.
+     */
     private List<KeyFrame> getKeyFrames(double angle, double duration, Paint color) {
         MFXProgressSpinner spinner = getSkinnable();
 
@@ -207,6 +244,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         return List.of(kf1, kf2, kf3, kf4);
     }
 
+    /**
+     * Updates the arc.
+     */
     private void updateArcLayout(double radius, double arcSize) {
         arc.setRadiusX(radius);
         arc.setRadiusY(radius);
@@ -220,6 +260,9 @@ public class MFXProgressSpinnerSkin extends SkinBase<MFXProgressSpinner> {
         track.setStrokeWidth(arc.getStrokeWidth());
     }
 
+    //================================================================================
+    // Override Methods
+    //================================================================================
     @Override
     protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
         MFXProgressSpinner spinner = getSkinnable();

+ 14 - 12
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTextFieldSkin.java

@@ -2,9 +2,10 @@ package io.github.palexdev.materialfx.skins;
 
 import io.github.palexdev.materialfx.controls.MFXIconWrapper;
 import io.github.palexdev.materialfx.controls.MFXTextField;
+import io.github.palexdev.materialfx.controls.factories.MFXAnimationFactory;
 import io.github.palexdev.materialfx.font.MFXFontIcon;
 import io.github.palexdev.materialfx.validation.MFXDialogValidator;
-import javafx.animation.FadeTransition;
+import javafx.animation.ScaleTransition;
 import javafx.scene.control.Label;
 import javafx.scene.control.skin.TextFieldSkin;
 import javafx.scene.input.MouseEvent;
@@ -42,7 +43,7 @@ public class MFXTextFieldSkin extends TextFieldSkin {
         focusLine.setStroke(textField.getLineColor());
         focusLine.setStrokeWidth(textField.getLineStrokeWidth());
         focusLine.setSmooth(true);
-        focusLine.setOpacity(0.0);
+        focusLine.setScaleX(0.0);
 
         line.endXProperty().bind(textField.widthProperty());
         focusLine.endXProperty().bind(textField.widthProperty());
@@ -111,19 +112,19 @@ public class MFXTextFieldSkin extends TextFieldSkin {
             }
 
             if (newValue) {
-                focusLine.setOpacity(1.0);
+                focusLine.setScaleX(1.0);
             } else {
-                focusLine.setOpacity(0.0);
+                focusLine.setScaleX(0.0);
             }
         });
 
         textField.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
-            if (textField.isAnimateLines() && focusLine.getOpacity() != 1.0) {
+            if (textField.isAnimateLines() && focusLine.getScaleX() != 1.0) {
                 buildAndPlayAnimation(true);
                 return;
             }
 
-            focusLine.setOpacity(1.0);
+            focusLine.setScaleX(1.0);
         });
 
         textField.isValidatedProperty().addListener((observable, oldValue, newValue) -> {
@@ -151,15 +152,16 @@ public class MFXTextFieldSkin extends TextFieldSkin {
      * Builds and play the lines animation if {@code animateLines} is true.
      */
     private void buildAndPlayAnimation(boolean focused) {
-        FadeTransition fadeTransition = new FadeTransition(Duration.millis(200), focusLine);
+        ScaleTransition scaleTransition = new ScaleTransition(Duration.millis(400), focusLine);
         if (focused) {
-            fadeTransition.setFromValue(0.0);
-            fadeTransition.setToValue(1.0);
+            scaleTransition.setFromX(0.0);
+            scaleTransition.setToX(1.0);
         } else {
-            fadeTransition.setFromValue(1.0);
-            fadeTransition.setToValue(0.0);
+            scaleTransition.setFromX(1.0);
+            scaleTransition.setToX(0.0);
         }
-        fadeTransition.play();
+        scaleTransition.setInterpolator(MFXAnimationFactory.getInterpolator());
+        scaleTransition.play();
     }
 
     //================================================================================

+ 2 - 3
materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTreeItemSkin.java

@@ -146,7 +146,7 @@ public class MFXTreeItemSkin<T> extends SkinBase<MFXTreeItem<T>> {
             }
             cell.updateCell(item);
         };
-        addListeners();
+        setListeners();
 
         if (item.isStartExpanded()) {
             forcedUpdate = true;
@@ -189,7 +189,7 @@ public class MFXTreeItemSkin<T> extends SkinBase<MFXTreeItem<T>> {
      * If that is not the case then we trigger the selection, retrieve the selection model and select the item.
      * @see io.github.palexdev.materialfx.controls.SelectionModel
      */
-    private void addListeners() {
+    private void setListeners() {
         MFXTreeItem<T> item = getSkinnable();
 
         item.getItems().addListener(itemsListener);
@@ -341,7 +341,6 @@ public class MFXTreeItemSkin<T> extends SkinBase<MFXTreeItem<T>> {
 
         AbstractMFXTreeCell<T> cell = item.getCellFactory().call(item);
         Node disclosureNode = cell.getDisclosureNode();
-        disclosureNode.setStyle("-fx-border-color: gold");
         disclosureNode.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
             if (item.getItems().isEmpty()) {
                 event.consume();

+ 1 - 9
materialfx/src/main/resources/io/github/palexdev/materialfx/css/mfx-checktreecell.css

@@ -1,9 +1 @@
-@import "mfx-treecell.css";
-
-.mfx-check-tree-cell:checked {
-    -fx-background-color: lightgreen;
-}
-
-.mfx-check-tree-cell:indeterminate {
-    -fx-background-color: lightblue;
-}
+@import "mfx-treecell.css";

+ 1 - 1
materialfx/src/main/resources/io/github/palexdev/materialfx/css/mfx-treecell.css

@@ -4,7 +4,7 @@
 }
 
 .mfx-tree-cell .ripple-generator {
-    -mfx-ripple-color: green;
+    -mfx-ripple-color: rgba(0, 190, 0, 0.4);
 }
 
 .mfx-tree-cell:selected {

+ 4 - 0
materialfx/src/main/resources/io/github/palexdev/materialfx/css/mfx-treeview.css

@@ -3,4 +3,8 @@
 .mfx-tree-view {
     -fx-padding: 3;
     -fx-border-insets: -1;
+    -fx-border-color: lightgray;
+    -fx-border-width: 1.5;
+    -fx-border-radius: 1.5;
+    -fx-background-radius: 1.5;
 }