🔖 Version 11.13.3
⬆️ Update Gradle plugins ⬆️ Update VirtualizedFX to 11.2.5 📝 Improve ROADMAP 📝 Update Text Fields wiki ✨ MFXTextField added a label to specify the unit of measure (optional, leave blank string to remove) Signed-off-by: palexdev <alessandro.parisi406@gmail.com>
This commit is contained in:
parent
39f5ceaa07
commit
cef28778eb
12
CHANGELOG.md
12
CHANGELOG.md
@ -15,6 +15,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
[//]: ##[Unreleased]
|
[//]: ##[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
|
## [11.13.2] - 09-02-2022
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
66
ROADMAP.md
66
ROADMAP.md
@ -1,18 +1,52 @@
|
|||||||
# TODOs and Future Plans
|
# TODOs and Future Plans
|
||||||
|
|
||||||
- [ ] *MFXCard*
|
# IMPORTANT!
|
||||||
- [ ] *MFXChipView(?)*
|
|
||||||
- [x] *MFXSlider*
|
A more complete roadmap is now available at [Trello](https://trello.com/b/RqRwBIRh/materialfx-roadmap)
|
||||||
- [ ] *MFXRangeSlider*
|
|
||||||
- [ ] *MFXHighlighter(?)*
|
## Priority Legend
|
||||||
<br></br>
|
|
||||||
- [ ] *MFXColorPicker*
|
- **HIGH**: you can expect the feature in the next major version
|
||||||
- [ ] *MFXDateTimePicker(?)*
|
- **LOW**: the feature will be implemented when I feel like it, or if the request is so high that it escalates to **
|
||||||
- [ ] *MFXTimePicker*
|
HIGH** priority
|
||||||
<br></br>
|
- **TBD**: the idea is there, the feature will be implemented at some point in the future
|
||||||
- [ ] *MFXCheckboxTableView*
|
|
||||||
- [ ] *Scrollable MFXTableView*
|
Note that you can influence the ROADMAP priority in two ways:
|
||||||
<br></br>
|
|
||||||
- [ ] *MFXToastNotification*
|
1) There's a high request for the feature
|
||||||
- [ ] *Improve Notification System(?)*
|
2) You can sponsor the project with the $50 one time tier
|
||||||
- [ ] *Introduce StringConverters for listviews' cells too?*
|
|
||||||
|
### 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 |
|
@ -1,10 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java-library'
|
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'
|
group 'io.github.palexdev'
|
||||||
version '11.13.2'
|
version '11.13.3'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'application'
|
id 'application'
|
||||||
id 'org.beryx.jlink' version '2.24.4'
|
id 'org.beryx.jlink' version '2.25.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -24,7 +24,7 @@ dependencies {
|
|||||||
implementation 'org.kordamp.ikonli:ikonli-core:12.2.0'
|
implementation 'org.kordamp.ikonli:ikonli-core:12.2.0'
|
||||||
implementation 'org.kordamp.ikonli:ikonli-javafx:12.2.0'
|
implementation 'org.kordamp.ikonli:ikonli-javafx:12.2.0'
|
||||||
implementation 'org.kordamp.ikonli:ikonli-fontawesome5-pack: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')
|
implementation project(':materialfx')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
module MaterialFX.Demo {
|
module MaterialFX.Demo {
|
||||||
requires MaterialFX;
|
requires MaterialFX;
|
||||||
|
requires VirtualizedFX;
|
||||||
|
|
||||||
requires jdk.localedata;
|
requires jdk.localedata;
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@ import javafx.application.Application;
|
|||||||
public class Launcher {
|
public class Launcher {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Application.launch(MagnifierTest.class, args);
|
Application.launch(Playground.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.MFXButton;
|
||||||
import io.github.palexdev.materialfx.controls.MFXSpinner;
|
import io.github.palexdev.materialfx.controls.MFXTextField;
|
||||||
import io.github.palexdev.materialfx.controls.models.spinner.ListSpinnerModel;
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.scenicview.ScenicView;
|
import org.scenicview.ScenicView;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Playground extends Application {
|
public class Playground extends Application {
|
||||||
|
private final double w = 445;
|
||||||
|
private final double h = 270;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) {
|
public void start(Stage primaryStage) {
|
||||||
CSSFX.start();
|
VBox vBox = new VBox(10);
|
||||||
BorderPane borderPane = new BorderPane();
|
vBox.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
ObservableList<String> strings = FXCollections.observableArrayList(
|
MFXTextField textField = new MFXTextField("15.0", "", "Pixels");
|
||||||
"String 1",
|
|
||||||
"String 2",
|
|
||||||
"String 3",
|
|
||||||
"String 4",
|
|
||||||
"String 5",
|
|
||||||
"String 6",
|
|
||||||
"String 7",
|
|
||||||
"String 8"
|
|
||||||
);
|
|
||||||
|
|
||||||
MFXSpinner<String> spinner = new MFXSpinner<>();
|
MFXButton button = new MFXButton("Change Measure Unit");
|
||||||
spinner.getStylesheets().add(MFXResourcesLoader.load("css/MFXSpinner.css"));
|
button.setOnAction(event -> {
|
||||||
spinner.setSpinnerModel(new ListSpinnerModel<>());
|
String measureUnit = textField.getMeasureUnit();
|
||||||
spinner.getSpinnerModel().setWrapAround(true);
|
measureUnit = (measureUnit == null || measureUnit.isEmpty()) ? "px" : "cm";
|
||||||
((ListSpinnerModel<String>) spinner.getSpinnerModel()).setItems(strings);
|
textField.setMeasureUnit(measureUnit);
|
||||||
spinner.setTextTransformer((focused, text) -> ((!focused || !spinner.isEditable()) && !text.isEmpty()) ? text + " cm" : text);
|
|
||||||
|
|
||||||
MFXButton add = new MFXButton("Add");
|
|
||||||
add.setOnAction(event -> ((ListSpinnerModel<String>) spinner.getSpinnerModel()).getItems().addAll(2, List.of("String Added 1", "String Added 2")));
|
|
||||||
MFXButton remove = new MFXButton("Remove");
|
|
||||||
remove.setOnAction(event -> ((ListSpinnerModel<String>) spinner.getSpinnerModel()).getItems().clear());
|
|
||||||
MFXButton removeSel = new MFXButton("Remove Selected");
|
|
||||||
removeSel.setOnAction(event -> ((ListSpinnerModel<String>) spinner.getSpinnerModel()).getItems().remove(((ListSpinnerModel<String>) spinner.getSpinnerModel()).getCurrentIndex()));
|
|
||||||
MFXButton replace = new MFXButton("Replace");
|
|
||||||
replace.setOnAction(event -> ((ListSpinnerModel<String>) spinner.getSpinnerModel()).getItems().set(((ListSpinnerModel<String>) spinner.getSpinnerModel()).getCurrentIndex(), "Replaced"));
|
|
||||||
MFXButton change = new MFXButton("Change List");
|
|
||||||
change.setOnAction(event -> {
|
|
||||||
ListSpinnerModel<String> model = (ListSpinnerModel<String>) spinner.getSpinnerModel();
|
|
||||||
model.setItems(FXCollections.observableArrayList(
|
|
||||||
"String 9",
|
|
||||||
"String 10",
|
|
||||||
"String 11",
|
|
||||||
"String 12",
|
|
||||||
"String 1234567890"
|
|
||||||
));
|
|
||||||
});
|
});
|
||||||
HBox box = new HBox(15, add, remove, removeSel, replace, change);
|
|
||||||
box.setAlignment(Pos.CENTER);
|
|
||||||
|
|
||||||
borderPane.setCenter(spinner);
|
vBox.getChildren().addAll(button, textField);
|
||||||
borderPane.setBottom(box);
|
Scene scene = new Scene(vBox, 800, 800);
|
||||||
Scene scene = new Scene(borderPane, 800, 600);
|
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
|
|
||||||
ScenicView.show(scene);
|
ScenicView.show(scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
demo/src/test/java/ScreenTest.java
Normal file
43
demo/src/test/java/ScreenTest.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'biz.aQute.bnd.builder' version '5.3.0'
|
id 'biz.aQute.bnd.builder' version '6.2.0'
|
||||||
id 'com.vanniktech.maven.publish' version '0.18.0'
|
id 'com.vanniktech.maven.publish' version '0.19.0'
|
||||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
id 'com.github.johnrengelman.shadow' version '7.1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -21,9 +21,9 @@ compileJava {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation('junit:junit:4.13.2')
|
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 {
|
javadoc {
|
||||||
@ -70,7 +70,7 @@ jar {
|
|||||||
shadowJar {
|
shadowJar {
|
||||||
mergeServiceFiles()
|
mergeServiceFiles()
|
||||||
dependencies {
|
dependencies {
|
||||||
include(dependency('io.github.palexdev:virtualizedfx:11.2.4'))
|
include(dependency('io.github.palexdev:virtualizedfx:11.2.5'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
GROUP=io.github.palexdev
|
GROUP=io.github.palexdev
|
||||||
POM_ARTIFACT_ID=materialfx
|
POM_ARTIFACT_ID=materialfx
|
||||||
VERSION_NAME=11.13.2
|
VERSION_NAME=11.13.3
|
||||||
|
|
||||||
POM_NAME=materialfx
|
POM_NAME=materialfx
|
||||||
POM_DESCRIPTION=Material Desgin components for JavaFX
|
POM_DESCRIPTION=Material Desgin components for JavaFX
|
||||||
|
@ -137,6 +137,8 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
|
|||||||
};
|
};
|
||||||
private static final PseudoClass FLOATING_PSEUDO_CLASS = PseudoClass.getPseudoClass("floating");
|
private static final PseudoClass FLOATING_PSEUDO_CLASS = PseudoClass.getPseudoClass("floating");
|
||||||
|
|
||||||
|
private final StringProperty measureUnit = new SimpleStringProperty("");
|
||||||
|
|
||||||
protected final MFXValidator validator = new MFXValidator();
|
protected final MFXValidator validator = new MFXValidator();
|
||||||
protected MFXContextMenu contextMenu;
|
protected MFXContextMenu contextMenu;
|
||||||
|
|
||||||
@ -579,6 +581,24 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
|
|||||||
return floating;
|
return floating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMeasureUnit() {
|
||||||
|
return measureUnit.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the unit of measure of the field.
|
||||||
|
* <p></p>
|
||||||
|
* 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
|
// Styleable Properties
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -631,6 +651,13 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
|
|||||||
10.0
|
10.0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private final StyleableDoubleProperty measureUnitGap = new StyleableDoubleProperty(
|
||||||
|
StyleableProperties.MEASURE_UNIT_GAP,
|
||||||
|
this,
|
||||||
|
"measureUnitGap",
|
||||||
|
5.0
|
||||||
|
);
|
||||||
|
|
||||||
private final StyleableBooleanProperty scaleOnAbove = new StyleableBooleanProperty(
|
private final StyleableBooleanProperty scaleOnAbove = new StyleableBooleanProperty(
|
||||||
StyleableProperties.SCALE_ON_ABOVE,
|
StyleableProperties.SCALE_ON_ABOVE,
|
||||||
this,
|
this,
|
||||||
@ -778,6 +805,21 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
|
|||||||
this.scaleOnAbove.set(scaleOnAbove);
|
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() {
|
public Color getTextFill() {
|
||||||
return textFill.get();
|
return textFill.get();
|
||||||
}
|
}
|
||||||
@ -865,6 +907,13 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
|
|||||||
10.0
|
10.0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static final CssMetaData<MFXTextField, Number> MEASURE_UNIT_GAP =
|
||||||
|
FACTORY.createSizeCssMetaData(
|
||||||
|
"-mfx-measure-unit-gap",
|
||||||
|
MFXTextField::measureUnitGapProperty,
|
||||||
|
5.0
|
||||||
|
);
|
||||||
|
|
||||||
private static final CssMetaData<MFXTextField, Boolean> SCALE_ON_ABOVE =
|
private static final CssMetaData<MFXTextField, Boolean> SCALE_ON_ABOVE =
|
||||||
FACTORY.createBooleanCssMetaData(
|
FACTORY.createBooleanCssMetaData(
|
||||||
"-mfx-scale-on-above",
|
"-mfx-scale-on-above",
|
||||||
@ -890,7 +939,7 @@ public class MFXTextField extends TextField implements Validated, MFXMenuControl
|
|||||||
cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
|
cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
|
||||||
TextField.getClassCssMetaData(),
|
TextField.getClassCssMetaData(),
|
||||||
ANIMATED, CARET_VISIBLE, BORDER_GAP,
|
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
|
SCALE_ON_ABOVE, TEXT_FILL, TEXT_LIMIT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
private final BoundTextField boundField;
|
private final BoundTextField boundField;
|
||||||
private final Label floatingText;
|
private final Label floatingText;
|
||||||
|
private final Label mUnitLabel;
|
||||||
|
|
||||||
private static final PseudoClass FOCUS_WITHIN_PSEUDO_CLASS = PseudoClass.getPseudoClass("focus-within");
|
private static final PseudoClass FOCUS_WITHIN_PSEUDO_CLASS = PseudoClass.getPseudoClass("focus-within");
|
||||||
|
|
||||||
@ -87,13 +88,18 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
floatingText.getTransforms().addAll(scale, translate);
|
floatingText.getTransforms().addAll(scale, translate);
|
||||||
if (textField.getFloatMode() == FloatMode.DISABLED) floatingText.setVisible(false);
|
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(
|
floating = Bindings.createBooleanBinding(
|
||||||
() -> getFloatY() != 0,
|
() -> getFloatY() != 0,
|
||||||
floatingPos
|
floatingPos
|
||||||
);
|
);
|
||||||
textField.floatingProperty().bind(floating);
|
textField.floatingProperty().bind(floating);
|
||||||
|
|
||||||
getChildren().setAll(floatingText, boundField);
|
getChildren().setAll(floatingText, boundField, mUnitLabel);
|
||||||
|
|
||||||
if (!shouldFloat()) {
|
if (!shouldFloat()) {
|
||||||
scale.setX(1);
|
scale.setX(1);
|
||||||
@ -142,6 +148,7 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
textField.requestLayout();
|
textField.requestLayout();
|
||||||
});
|
});
|
||||||
textField.floatingTextGapProperty().addListener((observable, oldValue, newValue) -> 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());
|
textField.borderGapProperty().addListener((observable, oldValue, newValue) -> textField.requestLayout());
|
||||||
|
|
||||||
// Focus Handling
|
// Focus Handling
|
||||||
@ -241,19 +248,6 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset);
|
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
|
@Override
|
||||||
protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
|
protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
|
||||||
MFXTextField textField = getSkinnable();
|
MFXTextField textField = getSkinnable();
|
||||||
@ -285,6 +279,20 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
return Math.max(iconsMax, height);
|
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
|
@Override
|
||||||
protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
|
protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
|
||||||
if (getSkinnable().getMaxWidth() == Double.MAX_VALUE) return Double.MAX_VALUE;
|
if (getSkinnable().getMaxWidth() == Double.MAX_VALUE) return Double.MAX_VALUE;
|
||||||
@ -303,6 +311,7 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
Node leading = textField.getLeadingIcon();
|
Node leading = textField.getLeadingIcon();
|
||||||
Node trailing = textField.getTrailingIcon();
|
Node trailing = textField.getTrailingIcon();
|
||||||
double graphicTextGap = textField.getGraphicTextGap();
|
double graphicTextGap = textField.getGraphicTextGap();
|
||||||
|
double mUnitGap = textField.getMeasureUnitGap();
|
||||||
FloatMode floatMode = textField.getFloatMode();
|
FloatMode floatMode = textField.getFloatMode();
|
||||||
VPos textVAlignment = (floatMode != FloatMode.INLINE) ? VPos.CENTER : VPos.BOTTOM;
|
VPos textVAlignment = (floatMode != FloatMode.INLINE) ? VPos.CENTER : VPos.BOTTOM;
|
||||||
double scaleValue = (floatMode == FloatMode.ABOVE && !textField.scaleOnAbove()) ? 1 : this.scaleValue;
|
double scaleValue = (floatMode == FloatMode.ABOVE && !textField.scaleOnAbove()) ? 1 : this.scaleValue;
|
||||||
@ -357,6 +366,18 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
);
|
);
|
||||||
floatingText.resizeRelocate(floatPos.getX(), floatPos.getY(), floatW, floatH);
|
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
|
// 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
|
// depends on the FloatMode, BOTTOM if FloatMode.INLINE, CENTER in every other mode
|
||||||
//
|
//
|
||||||
@ -364,7 +385,8 @@ public class MFXTextFieldSkin extends SkinBase<MFXTextField> {
|
|||||||
// minus the icon's width and gap
|
// minus the icon's width and gap
|
||||||
double textW = w -
|
double textW = w -
|
||||||
(leading != null ? leading.prefWidth(-1) + graphicTextGap : 0) -
|
(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);
|
double textH = boundField.prefHeight(-1);
|
||||||
PositionBean textPos = PositionUtils.computePosition(
|
PositionBean textPos = PositionUtils.computePosition(
|
||||||
textField,
|
textField,
|
||||||
|
@ -4,7 +4,7 @@ module MaterialFX {
|
|||||||
requires transitive javafx.graphics;
|
requires transitive javafx.graphics;
|
||||||
requires transitive java.desktop;
|
requires transitive java.desktop;
|
||||||
|
|
||||||
requires virtualizedfx;
|
requires VirtualizedFX;
|
||||||
|
|
||||||
exports io.github.palexdev.materialfx;
|
exports io.github.palexdev.materialfx;
|
||||||
|
|
||||||
|
@ -65,6 +65,11 @@
|
|||||||
-fx-text-fill: -mfx-main;
|
-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 {
|
.mfx-text-field .text-field {
|
||||||
-fx-text-box-border: transparent;
|
-fx-text-box-border: transparent;
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
|
@ -14,28 +14,30 @@
|
|||||||
|
|
||||||
### Properties
|
### Properties
|
||||||
|
|
||||||
| Property | Description | Type |
|
| Property | Description | Type |
|
||||||
| ------------ | ---------------------------------------------------------------- | -------:|
|
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------:|
|
||||||
| selectable | Specifies whether selection is allowed | Boolean |
|
| selectable | Specifies whether selection is allowed | Boolean |
|
||||||
| leadingIcon | Specifies the icon placed before the input field | Node |
|
| leadingIcon | Specifies the icon placed before the input field | Node |
|
||||||
| trailingIcon | Specifies the icon placed after the input field | Node |
|
| trailingIcon | Specifies the icon placed after the input field | Node |
|
||||||
| floatingText | Specifies the text of the floating text node | String |
|
| floatingText | Specifies the text of the floating text node | String |
|
||||||
| floating | Specifies if the floating text node is currently floating or not | Boolean |
|
| floating | Specifies if the floating text node is currently floating or not | Boolean |
|
||||||
|
| measureUnit | Specifies the unit of measure of the field. <br/>This is useful of course when dealing with numeric fields that represent for example: weight, volume, length and so on... | String |
|
||||||
|
|
||||||
### Styleable Properties
|
### Styleable Properties
|
||||||
|
|
||||||
| Property | Description | CSS Property | Type | Default Value |
|
| Property | Description | CSS Property | Type | Default Value |
|
||||||
| --------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- | ---------------:| ------------------------:|
|
| --------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- | ---------------:| ------------------------:|
|
||||||
| allowEdit | Specifies whether the field is editable | -mfx-editable | Boolean | true |
|
| allowEdit | Specifies whether the field is editable | -mfx-editable | Boolean | true |
|
||||||
| animated | Specifies whether the floating text positioning is animated | -mfx-animated | 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 |
|
| 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 |
|
| caretVisible | Specifies whether the caret should be visible | -mfx-caret-visible | Boolean | true |
|
||||||
| floatMode | Specifies how the floating text is positioned when floating.<br/>Can be: DISABLED, ABOVE, BORDER, INLINE | -mfx-float-mode | FloatMode[Enum] | INLINE |
|
| floatMode | Specifies how the floating text is positioned when floating.<br/>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 |
|
| 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 |
|
| 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 |
|
| measureUnitGap | Specifies the gap between the field and the measure unit label | -mfx-measure-unit-gap | Double | 5.0 |
|
||||||
| textFill | Specifies the text color | -fx-text-fill | Color | Color.rgb(0, 0, 0, 0.87) |
|
| 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 |
|
||||||
| textLimit | Specifies the maximum number of characters the field's text can have | -mfx-text-limit | Integer | -1(Unlimited) |
|
| 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
|
### CSS Selectors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user