Skip to content

Commit

Permalink
🔖 Version 11.13.5
Browse files Browse the repository at this point in the history
Controls Package
:bug: MFXTextField: fixed TextFormatter not working. It must be added on the BoundTextField, for this reason, added a delegate property (Fix for #174)

CSS Package
:recycle: MFXCSSBridge: do not take into account the Region's user agent stylesheet. If it's needed to specify the user agent the popup's getUserAgentStylesheet() method should be overridden inline, as well as for any other component that mey require it (see MFXComboBoxSkin as an example) (Fix for #173)

Selection Package
:recycle: Adds a method to retrieve the selection values as a List (rather than getSelection().values() which returns a generic Collection). Also make MultipleSelectionManager use LinkedHashSet and LinkedHashMap (TreeMap was used, oversight sorry) to keep insertion order for selection, this also ensures that building the values List returns the selected values in the same exact order as in the selection Map (Enhancement for #161)

Skins Package
:bug: MFXComboBoxSkin, MFXFilterComboBoxSkin: fixed an issue that prevented the combo box's popup from being fully customizable with CSS (Fix for #173)
:bug: MFXDatePickerSkin: initialize the picker's text if the initial date is not null (Fix for #172)

Signed-off-by: palexdev <alessandro.parisi406@gmail.com>
  • Loading branch information
palexdev committed Apr 11, 2022
1 parent c2dda93 commit dee6071
Show file tree
Hide file tree
Showing 17 changed files with 444 additions and 73 deletions.
68 changes: 50 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
(Date format is dd-MM-yyyy)

## Type of Changes
Expand All @@ -15,6 +16,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

[//]: ##[Unreleased]

## [11.13.5] - 11-04-2022

## Changed

- MFXCSSBridge: do not take into account the Region's user agent stylesheet. If it's needed to specify the user agent
the popup's getUserAgentStylesheet() method should be overridden inline, as well as for any other component that mey
require it (see MFXComboBoxSkin as an example) (Fix for #173)
- Adds a method to retrieve the selection values as a List (rather than getSelection().values() which returns a generic
Collection). Also make MultipleSelectionManager use LinkedHashSet and LinkedHashMap (TreeMap was used, oversight
sorry) to keep insertion order for selection, this also ensures that building the values List returns the selected
values in the same exact order as in the selection Map (Enhancement for #161)

## Fixed

- MFXTextField: fixed TextFormatter not working. It must be added on the BoundTextField, for this reason, added a
delegate property (Fix for #174)
- MFXComboBoxSkin, MFXFilterComboBoxSkin: fixed an issue that prevented the combo box's popup from being fully
customizable with CSS (Fix for #173)
- MFXDatePickerSkin: initialize the picker's text if the initial date is not null (Fix for #172)

## [11.13.4] - 31-03-2022

### Fixed
Expand All @@ -35,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improve ROADMAP

## [11.13.2] - 09-02-2022

### Added

- New control MFXMagnifierPane
Expand All @@ -46,12 +68,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added new control, MFXSpinner

### Changed

- ColorUtils: changed some method to be null-safe
- MFXFilterPaneSkin: properly compute the minimum width
- MFXTableViewSkin: allow to drag the filter dialog
- MFXIconWrapper: added handler to acquire focus

### Fixed

- MFXComboBoxSkin: ensure the caret position is at 0 if the combo box is not selectable
- MFXTableViewSkin: ensure the dialog is on foreground
- MFXTextField and all subclasses: fixed an issue with CSS and :focused PseudoClass. It was being ignored in some cases,
Expand All @@ -68,6 +92,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- ListChangeProcessor: fix findShift() method by including the given index in the count too

## [11.13.0] - 22-01-2022

_This version won't follow the above scheme as the amount of changes and commits is simply too huge and there would be
no way to correctly show all the changes without making mistakes (duplicates, "overlapping" changes...), for this reason
I'll try to sum up only the major changes below._
Expand All @@ -94,22 +119,29 @@ I'll try to sum up only the major changes below._
- The Filter API has been reviewed and now it's more powerful than ever with the new MFXFilterPane.
- The Validation API has been reviewed as well, it is as powerful as before thanks to JavaFX properties and observables,
but it's much more flexible. It's up to the user now to decide when and how to validate a control. Also an important
design choice has been made here. Many validation frameworks for JavaFX also offer a way to decorate a control,
but I decided to not to that as it would violate the Single Responsibility Principle! Validation has nothing to do with UI, plus depending on the fanciness of your App it's up to
you to decide how the validation controls will look like!
- Dialogs and Notifications have been reviewed as well. The dialogs have been simplified, and for notifications there are now two separate systems.
- The date picker is now on a whole new level, it's been remade from scratch and it's simply beautiful, powerful and versatile.
- There are also new components! MFXPopup is a PopupControl that actually works. Ever tried to style a PopupControl but no matter what the CSS would not work?
Do not worry about that never again, just use MFXPopup it's super easy thanks to my custom MFXCSSBridge (check documentation would be too much to write here haha).
MFXPagination has been made for MFXPaginatedTableViews, remade from scratch (meaning that doesn't extend Pagination) with a stunning modern look.
MFXTooltip, an alternative to JavaFX's tooltip, much more versatile!
- MFXRippleGenerator has been deprecated. The ripple generation is organized to be a new API, meaning that there are now interfaces and a base abstract class from which
you can implement new ripple generators. The new default implementation is MFXCircleRippleGenerator. The new API also allows you to create new Ripples by implementing the IRipple interface.
It's a rather advanced API tbh, but hey, it's there, who knows maybe someday I'll need it to be like this.
- MFXHLoader and MFXVLoader are no more. The loading API has been "extracted" to be independent from UI. MFXLoader has the same capabilities as the aforementioned controls
but it's not a Node. It's up to the user to decide how to manage the loaded views, and how to translate the loaded beans to a Node. (see the documentation and the DemoController for an example
on how to easily create a nav-bar even with the new API)
- The Selection API has been reviewed as well. It also supports the "extend selection" behavior when "Shift" is pressed, like you would expect from a file manager.
design choice has been made here. Many validation frameworks for JavaFX also offer a way to decorate a control, but I
decided to not to that as it would violate the Single Responsibility Principle! Validation has nothing to do with UI,
plus depending on the fanciness of your App it's up to you to decide how the validation controls will look like!
- Dialogs and Notifications have been reviewed as well. The dialogs have been simplified, and for notifications there
are now two separate systems.
- The date picker is now on a whole new level, it's been remade from scratch and it's simply beautiful, powerful and
versatile.
- There are also new components! MFXPopup is a PopupControl that actually works. Ever tried to style a PopupControl but
no matter what the CSS would not work? Do not worry about that never again, just use MFXPopup it's super easy thanks
to my custom MFXCSSBridge (check documentation would be too much to write here haha). MFXPagination has been made for
MFXPaginatedTableViews, remade from scratch (meaning that doesn't extend Pagination) with a stunning modern look.
MFXTooltip, an alternative to JavaFX's tooltip, much more versatile!
- MFXRippleGenerator has been deprecated. The ripple generation is organized to be a new API, meaning that there are now
interfaces and a base abstract class from which you can implement new ripple generators. The new default
implementation is MFXCircleRippleGenerator. The new API also allows you to create new Ripples by implementing the
IRipple interface. It's a rather advanced API tbh, but hey, it's there, who knows maybe someday I'll need it to be
like this.
- MFXHLoader and MFXVLoader are no more. The loading API has been "extracted" to be independent from UI. MFXLoader has
the same capabilities as the aforementioned controls but it's not a Node. It's up to the user to decide how to manage
the loaded views, and how to translate the loaded beans to a Node. (see the documentation and the DemoController for
an example on how to easily create a nav-bar even with the new API)
- The Selection API has been reviewed as well. It also supports the "extend selection" behavior when "Shift" is pressed,
like you would expect from a file manager.
- There is an insane amount of new utilities, for JavaFX as well as for Java

Again, let me **apologize** for this messy changelist, but I promise from next version changes will be tracked properly!
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ repositories {
}
dependencies {
implementation 'io.github.palexdev:materialfx:11.13.4'
implementation 'io.github.palexdev:materialfx:11.13.5'
}
```

Expand All @@ -235,7 +235,7 @@ dependencies {
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>materialfx</artifactId>
<version>11.13.4</version>
<version>11.13.5</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'io.github.palexdev'
version '11.13.4'
version '11.13.5'

repositories {
mavenCentral()
Expand Down
32 changes: 21 additions & 11 deletions demo/src/test/java/Playground.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
import io.github.palexdev.materialfx.controls.MFXButton;
import io.github.palexdev.materialfx.controls.MFXTextField;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.scenicview.ScenicView;

import java.text.DecimalFormat;
import java.text.ParsePosition;

public class Playground extends Application {
private final double w = 445;
private final double h = 270;

@Override
public void start(Stage primaryStage) {
VBox vBox = new VBox(10);
vBox.setAlignment(Pos.CENTER);

MFXTextField textField = new MFXTextField("15.0", "", "Pixels");
DecimalFormat format = new DecimalFormat("#.0");
MFXTextField field = new MFXTextField("", "", "Numbers");
field.delegateSetTextFormatter(new TextFormatter<>(c ->
{
if (c.getControlNewText().isEmpty()) {
return c;
}

ParsePosition parsePosition = new ParsePosition(0);
Object object = format.parse(c.getControlNewText(), parsePosition);

MFXButton button = new MFXButton("Change Measure Unit");
button.setOnAction(event -> {
String measureUnit = textField.getMeasureUnit();
measureUnit = (measureUnit == null || measureUnit.isEmpty()) ? "px" : "cm";
textField.setMeasureUnit(measureUnit);
});
if (object == null || parsePosition.getIndex() < c.getControlNewText().length()) {
return null;
} else {
return c;
}
}));

vBox.getChildren().addAll(button, textField);
vBox.getChildren().addAll(field);
Scene scene = new Scene(vBox, 800, 800);
primaryStage.setScene(scene);
primaryStage.show();
Expand Down
73 changes: 73 additions & 0 deletions demo/src/test/java/selection/MultipleSelectionModelTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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/>.
*/

package selection;

import io.github.palexdev.materialfx.selection.MultipleSelectionModel;
import io.github.palexdev.materialfx.utils.FXCollectors;
import javafx.collections.ObservableList;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class MultipleSelectionModelTests {
private final ObservableList<String> strings = IntStream.rangeClosed(0, 30)
.mapToObj(i -> "String " + i)
.collect(FXCollectors.toList());
private final MultipleSelectionModel<String> selectionModel = new MultipleSelectionModel<String>(strings);

@BeforeEach
public void setUp() {
selectionModel.clearSelection();
}

@Test
public void testOrder() {
Integer[] toSelect = {0, 6, 3, 9, 6};
selectionModel.selectIndexes(List.of(toSelect));

assertEquals(4, selectionModel.getSelection().size());

// Indexes
int i = 0;
Set<Integer> indexes = selectionModel.getSelection().keySet();
for (int val : indexes) {
assertEquals(toSelect[i], val);
i++;
}

// Values
i = 0;
String[] expected = {
"String 0",
"String 6",
"String 3",
"String 9"
};
List<String> values = selectionModel.getSelectedValues();
for (String value : values) {
assertEquals(expected[i], value);
i++;
}
}
}
72 changes: 72 additions & 0 deletions demo/src/test/resources/CustomCombo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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/>.
*/
.mfx-filter-combo-box {
-fx-background-color: derive(#323232, 20%);
-fx-border-color: transparent;
-mfx-caret-visible: false;
-mfx-float-mode: disabled;
-fx-text-fill: white;
}

.mfx-filter-combo-box .caret .mfx-ripple-generator {
-mfx-ripple-color: rgba(255, 255, 255, 0.2);
}

.mfx-filter-combo-box .caret .mfx-font-icon {
-mfx-color: white
}

.mfx-filter-combo-box .combo-popup .search-container {
-fx-background-color: derive(#323232, 20%);
-fx-background-radius: 5;
-fx-border-color: transparent;
-fx-padding: 10 5 5 5;
}

.mfx-filter-combo-box .combo-popup .search-field {
-fx-background-color: derive(#323232, 20%);
-fx-text-fill: white;
}

.mfx-filter-combo-box .combo-popup .search-field .text-field {
-fx-prompt-text-fill: #ebebeb;
}

.mfx-filter-combo-box .combo-popup .virtual-flow {
-fx-background-color: transparent;
}

.mfx-filter-combo-box .combo-popup .virtual-flow .mfx-combo-box-cell .data-label {
-fx-text-fill: white;
}

.mfx-filter-combo-box .combo-popup .virtual-flow .mfx-combo-box-cell:hover {
-fx-background-color: white;
}

.mfx-filter-combo-box .combo-popup .virtual-flow .mfx-combo-box-cell:hover .data-label {
-fx-text-fill: rgba(0, 0, 0, 0.87);
}

.mfx-filter-combo-box .combo-popup .virtual-flow .mfx-combo-box-cell:selected {
-fx-background-color: white;
}

.mfx-filter-combo-box .combo-popup .virtual-flow .mfx-combo-box-cell:selected .data-label {
-fx-text-fill: rgb(0, 0, 0, 0.87);
}
2 changes: 1 addition & 1 deletion materialfx/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GROUP=io.github.palexdev
POM_ARTIFACT_ID=materialfx
VERSION_NAME=11.13.4
VERSION_NAME=11.13.5

POM_NAME=materialfx
POM_DESCRIPTION=Material Desgin components for JavaFX
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import javafx.scene.control.IndexRange;
import javafx.scene.control.Skin;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.paint.Color;

Expand Down Expand Up @@ -422,6 +423,21 @@ public void replaceSelection(String replacement) {
boundField.replaceSelection(replacement);
}

public TextFormatter<?> delegateGetTextFormatter() {
return boundField.getTextFormatter();
}

/**
* Specifies the {@link BoundTextField} text formatter.
*/
public ObjectProperty<TextFormatter<?>> delegateTextFormatterProperty() {
return boundField.textFormatterProperty();
}

public void delegateSetTextFormatter(TextFormatter<?> textFormatter) {
boundField.setTextFormatter(textFormatter);
}

public int delegateGetAnchor() {
return boundField.getAnchor();
}
Expand Down

0 comments on commit dee6071

Please sign in to comment.