diff --git a/CHANGELOG.md b/CHANGELOG.md
index 799a2455..f146a609 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[//]: ##[Unreleased]
+## [11.13.3] - 10-03-2022
+
+### Added
+
+- MFXTextField: added a label to specify the unit of measure (optional, leave blank string to remove)
+
+### Changed
+
+- Update Gradle plugins
+- Update VirtualizedFX to 11.2.5
+- Improve ROADMAP
+
## [11.13.2] - 09-02-2022
### Added
diff --git a/ROADMAP.md b/ROADMAP.md
index cf9c491b..ab55da3a 100755
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -1,18 +1,52 @@
# TODOs and Future Plans
-- [ ] *MFXCard*
-- [ ] *MFXChipView(?)*
-- [x] *MFXSlider*
-- [ ] *MFXRangeSlider*
-- [ ] *MFXHighlighter(?)*
-
-- [ ] *MFXColorPicker*
-- [ ] *MFXDateTimePicker(?)*
-- [ ] *MFXTimePicker*
-
-- [ ] *MFXCheckboxTableView*
-- [ ] *Scrollable MFXTableView*
-
-- [ ] *MFXToastNotification*
-- [ ] *Improve Notification System(?)*
-- [ ] *Introduce StringConverters for listviews' cells too?*
\ No newline at end of file
+# IMPORTANT!
+
+A more complete roadmap is now available at [Trello](https://trello.com/b/RqRwBIRh/materialfx-roadmap)
+
+## Priority Legend
+
+- **HIGH**: you can expect the feature in the next major version
+- **LOW**: the feature will be implemented when I feel like it, or if the request is so high that it escalates to **
+ HIGH** priority
+- **TBD**: the idea is there, the feature will be implemented at some point in the future
+
+Note that you can influence the ROADMAP priority in two ways:
+
+1) There's a high request for the feature
+2) You can sponsor the project with the $50 one time tier
+
+### New Features
+
+| Priority | Feature | Notes |
+| -------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
+| **[HIGH]** | MFXColorPicker | |
+| **[HIGH]** | MFXToasts | |
+| **[HIGH]** | Screenshot Tool | |
+| **[HIGH]** | MFXTextArea | |
+| **[HIGH/TBD]** | NavBar/Drawer/TabPane/SideMenu | The idea is definitely there. But I still have to figure out the exact differences between those controls, which to implement and how to do it |
+| **[HIGH/TBD]** | Theme API and Dark Theme for MaterialFX controls | The idea is definitely there. But I still have to figure out the best way to implement it |
+| **[LOW]** | MFXCard | |
+| **[LOW]** | MFXCheckTableView | |
+| **[LOW]** | MFXChipView | |
+| **[LOW]** | MFXDateTimePicker | |
+| **[LOW]** | MFXRangeSlider | |
+| **[LOW]** | MFXTimePicker | |
+| **[LOW]** | MFXBadges | |
+| **[LOW]** | MFXAccordion | |
+| **[TBD]** | MFXCheckComboBox | |
+| **[TBD]** | MFXImageView | |
+| **[TBD]** | MFXHighlighter | |
+| **[TBD]** | MFXSplitButton | |
+| **[TBD]** | MFXProgressButton | |
+| **[TBD]** | MFXWaveProgressBar | |
+| **[TBD]** | MFXRate | |
+| **[TDB]** | Compare Slider | |
+
+### Improvements
+
+| Priority | Feature |
+| --------- | ------------------------------------- |
+| **[LOW]** | Further improve the NotifcationSystem |
+| **[LOW]** | Improve MFXSlider |
+| **[TBD]** | Auto completion for text fields |
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index c9885bce..c4e6ab7a 100755
--- a/build.gradle
+++ b/build.gradle
@@ -1,10 +1,10 @@
plugins {
id 'java-library'
- id 'org.openjfx.javafxplugin' version '0.0.11' apply false
+ id 'org.openjfx.javafxplugin' version '0.0.12' apply false
}
group 'io.github.palexdev'
-version '11.13.2'
+version '11.13.3'
repositories {
mavenCentral()
diff --git a/demo/build.gradle b/demo/build.gradle
index 79365384..324a0b65 100755
--- a/demo/build.gradle
+++ b/demo/build.gradle
@@ -1,6 +1,6 @@
plugins {
id 'application'
- id 'org.beryx.jlink' version '2.24.4'
+ id 'org.beryx.jlink' version '2.25.0'
}
repositories {
@@ -24,7 +24,7 @@ dependencies {
implementation 'org.kordamp.ikonli:ikonli-core:12.2.0'
implementation 'org.kordamp.ikonli:ikonli-javafx:12.2.0'
implementation 'org.kordamp.ikonli:ikonli-fontawesome5-pack:12.2.0'
- implementation 'io.github.palexdev:virtualizedfx:11.2.4'
+ implementation 'io.github.palexdev:virtualizedfx:11.2.5'
implementation project(':materialfx')
}
diff --git a/demo/src/main/java/module-info.java b/demo/src/main/java/module-info.java
index a3f637f8..83cb70d6 100755
--- a/demo/src/main/java/module-info.java
+++ b/demo/src/main/java/module-info.java
@@ -1,5 +1,6 @@
module MaterialFX.Demo {
requires MaterialFX;
+ requires VirtualizedFX;
requires jdk.localedata;
diff --git a/demo/src/test/java/Launcher.java b/demo/src/test/java/Launcher.java
index e051d53d..a81c1780 100755
--- a/demo/src/test/java/Launcher.java
+++ b/demo/src/test/java/Launcher.java
@@ -3,6 +3,6 @@ import javafx.application.Application;
public class Launcher {
public static void main(String[] args) {
- Application.launch(MagnifierTest.class, args);
+ Application.launch(Playground.class, args);
}
}
diff --git a/demo/src/test/java/Playground.java b/demo/src/test/java/Playground.java
index e3c3391b..c22acbc8 100755
--- a/demo/src/test/java/Playground.java
+++ b/demo/src/test/java/Playground.java
@@ -1,72 +1,35 @@
-import fr.brouillard.oss.cssfx.CSSFX;
-import io.github.palexdev.materialfx.MFXResourcesLoader;
import io.github.palexdev.materialfx.controls.MFXButton;
-import io.github.palexdev.materialfx.controls.MFXSpinner;
-import io.github.palexdev.materialfx.controls.models.spinner.ListSpinnerModel;
+import io.github.palexdev.materialfx.controls.MFXTextField;
import javafx.application.Application;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
-import javafx.scene.layout.BorderPane;
-import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.scenicview.ScenicView;
-import java.util.List;
-
public class Playground extends Application {
+ private final double w = 445;
+ private final double h = 270;
@Override
public void start(Stage primaryStage) {
- CSSFX.start();
- BorderPane borderPane = new BorderPane();
+ VBox vBox = new VBox(10);
+ vBox.setAlignment(Pos.CENTER);
- ObservableList strings = FXCollections.observableArrayList(
- "String 1",
- "String 2",
- "String 3",
- "String 4",
- "String 5",
- "String 6",
- "String 7",
- "String 8"
- );
+ MFXTextField textField = new MFXTextField("15.0", "", "Pixels");
- MFXSpinner spinner = new MFXSpinner<>();
- spinner.getStylesheets().add(MFXResourcesLoader.load("css/MFXSpinner.css"));
- spinner.setSpinnerModel(new ListSpinnerModel<>());
- spinner.getSpinnerModel().setWrapAround(true);
- ((ListSpinnerModel) spinner.getSpinnerModel()).setItems(strings);
- spinner.setTextTransformer((focused, text) -> ((!focused || !spinner.isEditable()) && !text.isEmpty()) ? text + " cm" : text);
-
- MFXButton add = new MFXButton("Add");
- add.setOnAction(event -> ((ListSpinnerModel) spinner.getSpinnerModel()).getItems().addAll(2, List.of("String Added 1", "String Added 2")));
- MFXButton remove = new MFXButton("Remove");
- remove.setOnAction(event -> ((ListSpinnerModel) spinner.getSpinnerModel()).getItems().clear());
- MFXButton removeSel = new MFXButton("Remove Selected");
- removeSel.setOnAction(event -> ((ListSpinnerModel) spinner.getSpinnerModel()).getItems().remove(((ListSpinnerModel) spinner.getSpinnerModel()).getCurrentIndex()));
- MFXButton replace = new MFXButton("Replace");
- replace.setOnAction(event -> ((ListSpinnerModel) spinner.getSpinnerModel()).getItems().set(((ListSpinnerModel) spinner.getSpinnerModel()).getCurrentIndex(), "Replaced"));
- MFXButton change = new MFXButton("Change List");
- change.setOnAction(event -> {
- ListSpinnerModel model = (ListSpinnerModel) spinner.getSpinnerModel();
- model.setItems(FXCollections.observableArrayList(
- "String 9",
- "String 10",
- "String 11",
- "String 12",
- "String 1234567890"
- ));
+ MFXButton button = new MFXButton("Change Measure Unit");
+ button.setOnAction(event -> {
+ String measureUnit = textField.getMeasureUnit();
+ measureUnit = (measureUnit == null || measureUnit.isEmpty()) ? "px" : "cm";
+ textField.setMeasureUnit(measureUnit);
});
- HBox box = new HBox(15, add, remove, removeSel, replace, change);
- box.setAlignment(Pos.CENTER);
- borderPane.setCenter(spinner);
- borderPane.setBottom(box);
- Scene scene = new Scene(borderPane, 800, 600);
+ vBox.getChildren().addAll(button, textField);
+ Scene scene = new Scene(vBox, 800, 800);
primaryStage.setScene(scene);
primaryStage.show();
+
ScenicView.show(scene);
}
}
diff --git a/demo/src/test/java/ScreenTest.java b/demo/src/test/java/ScreenTest.java
new file mode 100644
index 00000000..27d40b67
--- /dev/null
+++ b/demo/src/test/java/ScreenTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 Parisi Alessandro
+ * This file is part of MaterialFX (https://github.com/palexdev/MaterialFX).
+ *
+ * MaterialFX is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MaterialFX is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with MaterialFX. If not, see .
+ */
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.image.ImageView;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.robot.Robot;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+
+public class ScreenTest extends Application {
+
+ @Override
+ public void start(Stage primaryStage) throws Exception {
+ ImageView iv = new ImageView();
+
+ BorderPane bp = new BorderPane(iv);
+ Robot robot = new Robot();
+ WritableImage capture = robot.getScreenCapture(null, Screen.getPrimary().getBounds());
+ iv.setImage(capture);
+
+ Scene scene = new Scene(bp, 800, 800);
+ primaryStage.setScene(scene);
+ primaryStage.show();
+ }
+}
diff --git a/materialfx/build.gradle b/materialfx/build.gradle
index 2dfa65b1..e0efa110 100755
--- a/materialfx/build.gradle
+++ b/materialfx/build.gradle
@@ -1,9 +1,9 @@
import org.apache.tools.ant.taskdefs.condition.Os
plugins {
- id 'biz.aQute.bnd.builder' version '5.3.0'
- id 'com.vanniktech.maven.publish' version '0.18.0'
- id 'com.github.johnrengelman.shadow' version '7.0.0'
+ id 'biz.aQute.bnd.builder' version '6.2.0'
+ id 'com.vanniktech.maven.publish' version '0.19.0'
+ id 'com.github.johnrengelman.shadow' version '7.1.2'
}
repositories {
@@ -21,9 +21,9 @@ compileJava {
dependencies {
testImplementation('junit:junit:4.13.2')
- implementation 'com.vanniktech:gradle-maven-publish-plugin:0.18.0'
+ implementation 'com.vanniktech:gradle-maven-publish-plugin:0.19.0'
- implementation 'io.github.palexdev:virtualizedfx:11.2.4'
+ implementation 'io.github.palexdev:virtualizedfx:11.2.5'
}
javadoc {
@@ -70,7 +70,7 @@ jar {
shadowJar {
mergeServiceFiles()
dependencies {
- include(dependency('io.github.palexdev:virtualizedfx:11.2.4'))
+ include(dependency('io.github.palexdev:virtualizedfx:11.2.5'))
}
}
diff --git a/materialfx/gradle.properties b/materialfx/gradle.properties
index 37cd21a4..2088c0bc 100755
--- a/materialfx/gradle.properties
+++ b/materialfx/gradle.properties
@@ -1,6 +1,6 @@
GROUP=io.github.palexdev
POM_ARTIFACT_ID=materialfx
-VERSION_NAME=11.13.2
+VERSION_NAME=11.13.3
POM_NAME=materialfx
POM_DESCRIPTION=Material Desgin components for JavaFX
diff --git a/materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTextField.java b/materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTextField.java
index 5aa0778c..36078fa0 100644
--- a/materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTextField.java
+++ b/materialfx/src/main/java/io/github/palexdev/materialfx/controls/MFXTextField.java
@@ -137,6 +137,8 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
};
private static final PseudoClass FLOATING_PSEUDO_CLASS = PseudoClass.getPseudoClass("floating");
+ private final StringProperty measureUnit = new SimpleStringProperty("");
+
protected final MFXValidator validator = new MFXValidator();
protected MFXContextMenu contextMenu;
@@ -579,6 +581,24 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
return floating;
}
+ public String getMeasureUnit() {
+ return measureUnit.get();
+ }
+
+ /**
+ * Specifies the unit of measure of the field.
+ *
+ * This is useful of course when dealing with numeric fields that represent for example:
+ * weight, volume, length and so on...
+ */
+ public StringProperty measureUnitProperty() {
+ return measureUnit;
+ }
+
+ public void setMeasureUnit(String measureUnit) {
+ this.measureUnit.set(measureUnit);
+ }
+
//================================================================================
// Styleable Properties
//================================================================================
@@ -631,6 +651,13 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
10.0
);
+ private final StyleableDoubleProperty measureUnitGap = new StyleableDoubleProperty(
+ StyleableProperties.MEASURE_UNIT_GAP,
+ this,
+ "measureUnitGap",
+ 5.0
+ );
+
private final StyleableBooleanProperty scaleOnAbove = new StyleableBooleanProperty(
StyleableProperties.SCALE_ON_ABOVE,
this,
@@ -778,6 +805,21 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
this.scaleOnAbove.set(scaleOnAbove);
}
+ public double getMeasureUnitGap() {
+ return measureUnitGap.get();
+ }
+
+ /**
+ * Specifies the gap between the field and the measure unit label.
+ */
+ public StyleableDoubleProperty measureUnitGapProperty() {
+ return measureUnitGap;
+ }
+
+ public void setMeasureUnitGap(double measureUnitGap) {
+ this.measureUnitGap.set(measureUnitGap);
+ }
+
public Color getTextFill() {
return textFill.get();
}
@@ -865,6 +907,13 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
10.0
);
+ private static final CssMetaData MEASURE_UNIT_GAP =
+ FACTORY.createSizeCssMetaData(
+ "-mfx-measure-unit-gap",
+ MFXTextField::measureUnitGapProperty,
+ 5.0
+ );
+
private static final CssMetaData SCALE_ON_ABOVE =
FACTORY.createBooleanCssMetaData(
"-mfx-scale-on-above",
@@ -890,7 +939,7 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
TextField.getClassCssMetaData(),
ANIMATED, CARET_VISIBLE, BORDER_GAP,
- EDITABLE, FLOAT_MODE, FLOATING_TEXT_GAP, GRAPHIC_TEXT_GAP,
+ EDITABLE, FLOAT_MODE, FLOATING_TEXT_GAP, GRAPHIC_TEXT_GAP, MEASURE_UNIT_GAP,
SCALE_ON_ABOVE, TEXT_FILL, TEXT_LIMIT
);
}
diff --git a/materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTextFieldSkin.java b/materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTextFieldSkin.java
index d09df031..7a95fdde 100644
--- a/materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTextFieldSkin.java
+++ b/materialfx/src/main/java/io/github/palexdev/materialfx/skins/MFXTextFieldSkin.java
@@ -62,6 +62,7 @@ public class MFXTextFieldSkin extends SkinBase {
//================================================================================
private final BoundTextField boundField;
private final Label floatingText;
+ private final Label mUnitLabel;
private static final PseudoClass FOCUS_WITHIN_PSEUDO_CLASS = PseudoClass.getPseudoClass("focus-within");
@@ -87,13 +88,18 @@ public class MFXTextFieldSkin extends SkinBase {
floatingText.getTransforms().addAll(scale, translate);
if (textField.getFloatMode() == FloatMode.DISABLED) floatingText.setVisible(false);
+ mUnitLabel = new Label();
+ mUnitLabel.getStyleClass().setAll("measure-unit");
+ mUnitLabel.textProperty().bind(textField.measureUnitProperty());
+ mUnitLabel.visibleProperty().bind(textField.measureUnitProperty().isNotNull().and(textField.measureUnitProperty().isNotEmpty()));
+
floating = Bindings.createBooleanBinding(
() -> getFloatY() != 0,
floatingPos
);
textField.floatingProperty().bind(floating);
- getChildren().setAll(floatingText, boundField);
+ getChildren().setAll(floatingText, boundField, mUnitLabel);
if (!shouldFloat()) {
scale.setX(1);
@@ -142,6 +148,7 @@ public class MFXTextFieldSkin extends SkinBase {
textField.requestLayout();
});
textField.floatingTextGapProperty().addListener((observable, oldValue, newValue) -> textField.requestLayout());
+ textField.measureUnitGapProperty().addListener((observable, oldValue, newValue) -> textField.requestLayout());
textField.borderGapProperty().addListener((observable, oldValue, newValue) -> textField.requestLayout());
// Focus Handling
@@ -241,19 +248,6 @@ public class MFXTextFieldSkin extends SkinBase {
return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset);
}
- @Override
- protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- MFXTextField textField = getSkinnable();
- Node leading = textField.getLeadingIcon();
- Node trailing = textField.getTrailingIcon();
- double gap = textField.getGraphicTextGap();
- return leftInset +
- (leading != null ? leading.prefWidth(-1) + gap : 0) +
- Math.max(boundField.prefWidth(-1), floatingText.prefWidth(-1)) +
- (trailing != null ? trailing.prefWidth(-1) + gap : 0) +
- rightInset;
- }
-
@Override
protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
MFXTextField textField = getSkinnable();
@@ -285,6 +279,20 @@ public class MFXTextFieldSkin extends SkinBase {
return Math.max(iconsMax, height);
}
+ @Override
+ protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ MFXTextField textField = getSkinnable();
+ Node leading = textField.getLeadingIcon();
+ Node trailing = textField.getTrailingIcon();
+ double gap = textField.getGraphicTextGap();
+ double mUnitGap = textField.getMeasureUnitGap();
+ return leftInset +
+ (leading != null ? leading.prefWidth(-1) + gap : 0) +
+ Math.max(boundField.prefWidth(-1) + mUnitLabel.prefWidth(-1) + mUnitGap, floatingText.prefWidth(-1)) +
+ (trailing != null ? trailing.prefWidth(-1) + gap : 0) +
+ rightInset;
+ }
+
@Override
protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
if (getSkinnable().getMaxWidth() == Double.MAX_VALUE) return Double.MAX_VALUE;
@@ -303,6 +311,7 @@ public class MFXTextFieldSkin extends SkinBase {
Node leading = textField.getLeadingIcon();
Node trailing = textField.getTrailingIcon();
double graphicTextGap = textField.getGraphicTextGap();
+ double mUnitGap = textField.getMeasureUnitGap();
FloatMode floatMode = textField.getFloatMode();
VPos textVAlignment = (floatMode != FloatMode.INLINE) ? VPos.CENTER : VPos.BOTTOM;
double scaleValue = (floatMode == FloatMode.ABOVE && !textField.scaleOnAbove()) ? 1 : this.scaleValue;
@@ -357,6 +366,18 @@ public class MFXTextFieldSkin extends SkinBase {
);
floatingText.resizeRelocate(floatPos.getX(), floatPos.getY(), floatW, floatH);
+ // Position the Label responsible for showing the measure unit
+ double unitW = mUnitLabel.prefWidth(-1);
+ double unitH = mUnitLabel.prefHeight(-1);
+ PositionBean unitPos = PositionUtils.computePosition(
+ textField,
+ mUnitLabel,
+ x, y, w, h, 0,
+ Insets.EMPTY,
+ HPos.RIGHT, textVAlignment
+ );
+ mUnitLabel.resizeRelocate(unitPos.getX(), unitPos.getY(), unitW, unitH);
+
// The text is always positioned to the LEFT of the Pane, the vertical alignment
// depends on the FloatMode, BOTTOM if FloatMode.INLINE, CENTER in every other mode
//
@@ -364,7 +385,8 @@ public class MFXTextFieldSkin extends SkinBase {
// minus the icon's width and gap
double textW = w -
(leading != null ? leading.prefWidth(-1) + graphicTextGap : 0) -
- (trailing != null ? trailing.prefWidth(-1) + graphicTextGap : 0);
+ (trailing != null ? trailing.prefWidth(-1) + graphicTextGap : 0) -
+ unitW - mUnitGap;
double textH = boundField.prefHeight(-1);
PositionBean textPos = PositionUtils.computePosition(
textField,
diff --git a/materialfx/src/main/java/module-info.java b/materialfx/src/main/java/module-info.java
index 0235db42..61d2296c 100755
--- a/materialfx/src/main/java/module-info.java
+++ b/materialfx/src/main/java/module-info.java
@@ -4,7 +4,7 @@ module MaterialFX {
requires transitive javafx.graphics;
requires transitive java.desktop;
- requires virtualizedfx;
+ requires VirtualizedFX;
exports io.github.palexdev.materialfx;
diff --git a/materialfx/src/main/resources/io/github/palexdev/materialfx/css/MFXTextField.css b/materialfx/src/main/resources/io/github/palexdev/materialfx/css/MFXTextField.css
index 6f21e030..94677c23 100755
--- a/materialfx/src/main/resources/io/github/palexdev/materialfx/css/MFXTextField.css
+++ b/materialfx/src/main/resources/io/github/palexdev/materialfx/css/MFXTextField.css
@@ -65,6 +65,11 @@
-fx-text-fill: -mfx-main;
}
+.mfx-text-field .measure-unit {
+ -fx-font-family: "Open Sans Regular";
+ -fx-text-fill: -mfx-text-he;
+}
+
.mfx-text-field .text-field {
-fx-text-box-border: transparent;
-fx-background-color: transparent;
diff --git a/wiki/Text Fields.md b/wiki/Text Fields.md
index b44ccfbc..df258441 100644
--- a/wiki/Text Fields.md
+++ b/wiki/Text Fields.md
@@ -14,28 +14,30 @@
### Properties
-| Property | Description | Type |
-| ------------ | ---------------------------------------------------------------- | -------:|
-| selectable | Specifies whether selection is allowed | Boolean |
-| leadingIcon | Specifies the icon placed before the input field | Node |
-| trailingIcon | Specifies the icon placed after the input field | Node |
-| floatingText | Specifies the text of the floating text node | String |
-| floating | Specifies if the floating text node is currently floating or not | Boolean |
+| Property | Description | Type |
+| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------:|
+| selectable | Specifies whether selection is allowed | Boolean |
+| leadingIcon | Specifies the icon placed before the input field | Node |
+| trailingIcon | Specifies the icon placed after the input field | Node |
+| floatingText | Specifies the text of the floating text node | String |
+| floating | Specifies if the floating text node is currently floating or not | Boolean |
+| measureUnit | Specifies the unit of measure of the field.
This is useful of course when dealing with numeric fields that represent for example: weight, volume, length and so on... | String |
### Styleable Properties
-| Property | Description | CSS Property | Type | Default Value |
-| --------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- | ---------------:| ------------------------:|
-| allowEdit | Specifies whether the field is editable | -mfx-editable | Boolean | true |
-| animated | Specifies whether the floating text positioning is animated | -mfx-animated | Boolean | true |
-| borderGap | For FloatMode.BORDER FloatMode.ABOVE modes, this specifies the distance from the control's x origin (padding not included) | -mfx-border-gap | Double | 10.0 |
-| caretVisible | Specifies whether the caret should be visible | -mfx-caret-visible | Boolean | true |
-| floatMode | Specifies how the floating text is positioned when floating.
Can be: DISABLED, ABOVE, BORDER, INLINE | -mfx-float-mode | FloatMode[Enum] | INLINE |
-| floatingTextGap | For FloatMode.INLINE mode, this specifies the gap between the floating text node and the input field node | -mfx-gap | Double | 5.0 |
-| graphicTextGap | Specifies the gap between the input field and the icons | -fx-graphic-text-gap | Double | 10.0 |
-| scaleOnAbove | Specifies whether the floating text node should be scaled or not when the float mode is set to FloatMode.ABOVE | -mfx-scale-on-above | Boolean | false |
-| textFill | Specifies the text color | -fx-text-fill | Color | Color.rgb(0, 0, 0, 0.87) |
-| textLimit | Specifies the maximum number of characters the field's text can have | -mfx-text-limit | Integer | -1(Unlimited) |
+| Property | Description | CSS Property | Type | Default Value |
+| --------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- | ---------------:| ------------------------:|
+| allowEdit | Specifies whether the field is editable | -mfx-editable | Boolean | true |
+| animated | Specifies whether the floating text positioning is animated | -mfx-animated | Boolean | true |
+| borderGap | For FloatMode.BORDER FloatMode.ABOVE modes, this specifies the distance from the control's x origin (padding not included) | -mfx-border-gap | Double | 10.0 |
+| caretVisible | Specifies whether the caret should be visible | -mfx-caret-visible | Boolean | true |
+| floatMode | Specifies how the floating text is positioned when floating.
Can be: DISABLED, ABOVE, BORDER, INLINE | -mfx-float-mode | FloatMode[Enum] | INLINE |
+| floatingTextGap | For FloatMode.INLINE mode, this specifies the gap between the floating text node and the input field node | -mfx-gap | Double | 5.0 |
+| graphicTextGap | Specifies the gap between the input field and the icons | -fx-graphic-text-gap | Double | 10.0 |
+| measureUnitGap | Specifies the gap between the field and the measure unit label | -mfx-measure-unit-gap | Double | 5.0 |
+| scaleOnAbove | Specifies whether the floating text node should be scaled or not when the float mode is set to FloatMode.ABOVE | -mfx-scale-on-above | Boolean | false |
+| textFill | Specifies the text color | -fx-text-fill | Color | Color.rgb(0, 0, 0, 0.87) |
+| textLimit | Specifies the maximum number of characters the field's text can have | -mfx-text-limit | Integer | -1(Unlimited) |
### CSS Selectors