🐛 Fix inconsistent filters (#313)
Signed-off-by: palexdev <alessandro.parisi406@gmail.com>
This commit is contained in:
parent
6a6b5b5675
commit
7aa2c5330f
@ -2,9 +2,9 @@ import io.github.palexdev.materialfx.controls.MFXButton;
|
||||
import io.github.palexdev.materialfx.controls.MFXContextMenu;
|
||||
import io.github.palexdev.materialfx.controls.MFXContextMenuItem;
|
||||
import io.github.palexdev.materialfx.factories.InsetsFactory;
|
||||
import io.github.palexdev.mfxresources.fonts.MFXFontIcon;
|
||||
import io.github.palexdev.materialfx.utils.ColorUtils;
|
||||
import io.github.palexdev.materialfx.utils.StringUtils;
|
||||
import io.github.palexdev.mfxresources.fonts.fontawesome.FontAwesomeSolid;
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
@ -24,10 +24,10 @@ public class ContextTest extends Application {
|
||||
Label labelSeparator = new Label("Separator");
|
||||
labelSeparator.setPadding(InsetsFactory.of(5, 3, 5, 0));
|
||||
menu.addSeparator(labelSeparator);
|
||||
menu.addItem(new MFXContextMenuItem("Separated Item", MFXFontIcon.getRandomIcon(12, ColorUtils.getRandomColor())));
|
||||
menu.addItem(new MFXContextMenuItem("Separated Item", FontAwesomeSolid.random(ColorUtils.getRandomColor(), 12)));
|
||||
|
||||
menu.addLineSeparator(MFXContextMenu.Builder.getLineSeparator());
|
||||
menu.addItem(new MFXContextMenuItem("LSeparated Item", MFXFontIcon.getRandomIcon(12, ColorUtils.getRandomColor())));
|
||||
menu.addItem(new MFXContextMenuItem("LSeparated Item", FontAwesomeSolid.random(ColorUtils.getRandomColor(), 12)));
|
||||
|
||||
menu.install();
|
||||
|
||||
@ -40,7 +40,7 @@ public class ContextTest extends Application {
|
||||
private void populateMenu(MFXContextMenu menu, int num) {
|
||||
MFXContextMenuItem[] items = new MFXContextMenuItem[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
MFXContextMenuItem item = new MFXContextMenuItem("Menu Item " + (i + 1), MFXFontIcon.getRandomIcon(12, ColorUtils.getRandomColor()));
|
||||
MFXContextMenuItem item = new MFXContextMenuItem("Menu Item " + (i + 1), FontAwesomeSolid.random(ColorUtils.getRandomColor(), 12));
|
||||
item.setAccelerator("Alt + " + StringUtils.randAlphabetic(1).toUpperCase());
|
||||
items[i] = item;
|
||||
}
|
||||
|
@ -1,35 +1,26 @@
|
||||
import io.github.palexdev.materialfx.controls.MFXComboBox;
|
||||
import io.github.palexdev.materialfx.controls.MFXTableColumn;
|
||||
import io.github.palexdev.materialfx.controls.MFXTableView;
|
||||
import io.github.palexdev.materialfx.controls.cell.MFXTableRowCell;
|
||||
import io.github.palexdev.materialfx.demo.model.Model;
|
||||
import io.github.palexdev.materialfx.demo.model.Person;
|
||||
import io.github.palexdev.materialfx.filter.IntegerFilter;
|
||||
import io.github.palexdev.materialfx.filter.StringFilter;
|
||||
import io.github.palexdev.materialfx.theming.CSSFragment;
|
||||
import io.github.palexdev.materialfx.theming.JavaFXThemes;
|
||||
import io.github.palexdev.materialfx.theming.MaterialFXStylesheets;
|
||||
import io.github.palexdev.materialfx.theming.UserAgentBuilder;
|
||||
import io.github.palexdev.mfxcore.builders.InsetsBuilder;
|
||||
import javafx.application.Application;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class Reproducer extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
VBox box = new VBox(20);
|
||||
box.setAlignment(Pos.TOP_CENTER);
|
||||
box.setPadding(new Insets(20));
|
||||
|
||||
UserAgentBuilder.builder()
|
||||
.themes(JavaFXThemes.MODENA)
|
||||
.themes(MaterialFXStylesheets.forAssemble(true))
|
||||
.setResolveAssets(true)
|
||||
.setDeploy(true)
|
||||
.build()
|
||||
.setGlobal();
|
||||
StackPane pane = new StackPane();
|
||||
pane.setPadding(InsetsBuilder.all(10));
|
||||
|
||||
MFXTableView<Person> table = new MFXTableView<>(Model.people);
|
||||
MFXTableColumn<Person> name = new MFXTableColumn<>("Name");
|
||||
@ -39,7 +30,14 @@ public class Reproducer extends Application {
|
||||
MFXTableColumn<Person> age = new MFXTableColumn<>("Age");
|
||||
age.setRowCellFactory(p -> new MFXTableRowCell<>(Person::getAge));
|
||||
table.getTableColumns().addAll(name, surname, age);
|
||||
box.getChildren().add(table);
|
||||
pane.getChildren().add(table);
|
||||
table.setMinSize(400.0, 400.0);
|
||||
|
||||
table.getFilters().addAll(
|
||||
new StringFilter<>("Name", Person::getName),
|
||||
new StringFilter<>("Surname", Person::getSurname),
|
||||
new IntegerFilter<>("Age", Person::getAge)
|
||||
);
|
||||
|
||||
CSSFragment.Builder.build()
|
||||
.addSelector(".mfx-filter-pane")
|
||||
@ -47,15 +45,14 @@ public class Reproducer extends Application {
|
||||
.closeSelector()
|
||||
.applyOn(table);
|
||||
|
||||
MFXComboBox<String> combo = new MFXComboBox<>(Model.strings);
|
||||
box.getChildren().add(combo);
|
||||
CSSFragment.Builder.build()
|
||||
.addSelector(".mfx-combo-box .combo-popup .virtual-flow")
|
||||
.addStyle("-fx-background-color: gold")
|
||||
.closeSelector()
|
||||
.applyOn(combo);
|
||||
|
||||
Scene scene = new Scene(box, 400, 400);
|
||||
UserAgentBuilder.builder()
|
||||
.themes(JavaFXThemes.MODENA)
|
||||
.themes(MaterialFXStylesheets.forAssemble(false))
|
||||
.setResolveAssets(true)
|
||||
.setDeploy(true)
|
||||
.build()
|
||||
.setGlobal();
|
||||
Scene scene = new Scene(pane, 600, 600);
|
||||
stage.setScene(scene);
|
||||
stage.show();
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import java.util.function.Predicate;
|
||||
* It wraps the following data:
|
||||
* <p> - A String which is the query
|
||||
* <p> - An object of type {@link AbstractFilter}, which is effectively responsible for producing the {@link Predicate}
|
||||
* <p> - A {@link BiPredicateBean}, which is used by {@link AbstractFilter}, see {@link AbstractFilter#predicateFor(String)} or {@link AbstractFilter#predicateFor(String, BiPredicate)}
|
||||
* <p> - A {@link BiPredicateBean}, which is used by {@link AbstractFilter}, see {@link AbstractFilter#predicateFor(String, FilterBean)}
|
||||
* <p> - A {@link ChainMode} enumeration to specify how this filter should be combined with other filters
|
||||
*
|
||||
* @param <T> the type of objects to filter
|
||||
@ -65,10 +65,10 @@ public class FilterBean<T, U> {
|
||||
//================================================================================
|
||||
|
||||
/**
|
||||
* Calls {@link AbstractFilter#predicateFor(String)} with the query specified by this bean.
|
||||
* Calls {@link AbstractFilter#predicateFor(String, FilterBean)} with the query specified by this bean.
|
||||
*/
|
||||
public Predicate<T> predicate() {
|
||||
return filter.predicateFor(query);
|
||||
return filter.predicateFor(query, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ import java.util.function.Predicate;
|
||||
* To make the filter system flexible and yet highly specialized, every implementation must specify a
|
||||
* {@link StringConverter} which is used to convert the query to an object of type U.
|
||||
* <p></p>
|
||||
* At this point we have all the basic elements to describe how the {@link Predicate} is predicate is produced.
|
||||
* At this point we have all the basic elements to describe how the {@link Predicate} is produced.
|
||||
* Every implementation of this base class has some predefined {@link BiPredicate} which operate on U objects.
|
||||
* The query is converted to an object of type U, and the extractor gets the U field from a T object, both U
|
||||
* objects are fed to the {@link BiPredicate}. In code:
|
||||
@ -131,6 +131,12 @@ public abstract class AbstractFilter<T, U> {
|
||||
* return t -> biPredicate.test(extractor.apply(t), convertedQuery);
|
||||
* }
|
||||
* </pre>
|
||||
* <p></p>
|
||||
* <b>WARN:</b> this method should not be used to convert {@link FilterBean}s to {@link Predicate}.
|
||||
* A {@link FilterBean} already has a {@link BiPredicate} that specifies its filter behavior. This method instead
|
||||
* selects a {@link BiPredicate} according to the value of {@link #selectedPredicateIndexProperty()}, which may have
|
||||
* changed since the creation of the {@link FilterBean}, leading to another filter being used instead.
|
||||
* For this reason, use {@link #predicateFor(String, FilterBean)} instead.
|
||||
*/
|
||||
public Predicate<T> predicateFor(String input) {
|
||||
checkIndex();
|
||||
@ -153,15 +159,11 @@ public abstract class AbstractFilter<T, U> {
|
||||
* }
|
||||
* </pre>
|
||||
* <p></p>
|
||||
* <b>WARN:</b> to be honest this method should have been removed but I wanted to keep it
|
||||
* since it adds some flexibility to the filter system. Note that using this method may lead
|
||||
* to inconsistencies in UI controls since the given argument is not a {@link BiPredicateBean},
|
||||
* which means that it won't be added to the predicates list of this filter, and the selected predicate index
|
||||
* property won't be updated. This also means that any other method that relies on that index will fail.
|
||||
* This is used by {@link FilterBean}s to convert themselves into a {@link Predicate}.
|
||||
*/
|
||||
public Predicate<T> predicateFor(String input, BiPredicate<U, U> biPredicate) {
|
||||
public Predicate<T> predicateFor(String input, FilterBean<T, U> bean) {
|
||||
U convertedInput = getValue(input);
|
||||
return t -> biPredicate.test(extractor.apply(t), convertedInput);
|
||||
return t -> bean.getPredicateBean().predicate().test(extractor.apply(t), convertedInput);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user