♻️ MFXComboBox, MFXComboBoxSkin, MFXFilterComboBoxSkin: improvement for issue #243, allow to easily dimension the combo popup by setting the number of rows to show in the list

♻️ MFXFilterComboBoxSkin: do not create a new instance of SimpleVirtualFlow, use the one in the superclass instead
🚚 Renamed GenericAddRemoveChange to NonIterableChange as it was causing compilation issues from time to time

Signed-off-by: Alessadro Parisi <alessandro.parisi406@gmail.com>
This commit is contained in:
Alessadro Parisi 2023-03-16 12:08:44 +01:00
parent 58fd4def40
commit b9cf071b9a
4 changed files with 66 additions and 4 deletions

View File

@ -26,6 +26,7 @@ import io.github.palexdev.materialfx.beans.properties.functional.BiFunctionPrope
import io.github.palexdev.materialfx.beans.properties.functional.ConsumerProperty;
import io.github.palexdev.materialfx.beans.properties.functional.FunctionProperty;
import io.github.palexdev.materialfx.beans.properties.styleable.StyleableBooleanProperty;
import io.github.palexdev.materialfx.beans.properties.styleable.StyleableIntegerProperty;
import io.github.palexdev.materialfx.controls.base.MFXCombo;
import io.github.palexdev.materialfx.controls.cell.MFXComboBoxCell;
import io.github.palexdev.materialfx.font.MFXFontIcon;
@ -387,6 +388,13 @@ public class MFXComboBox<T> extends MFXTextField implements MFXCombo<T> {
//================================================================================
// Styleable Properties
//================================================================================
private final StyleableIntegerProperty rowsCount = new StyleableIntegerProperty(
StyleableProperties.ROWS_COUNT,
this,
"rowsCount",
10
);
private final StyleableBooleanProperty scrollOnOpen = new StyleableBooleanProperty(
StyleableProperties.SCROLL_ON_OPEN,
this,
@ -394,6 +402,21 @@ public class MFXComboBox<T> extends MFXTextField implements MFXCombo<T> {
false
);
public int getRowsCount() {
return rowsCount.get();
}
/**
* Specifies the number of rows to show in the list, this determines the height of the popup.
*/
public StyleableIntegerProperty rowsCountProperty() {
return rowsCount;
}
public void setRowsCount(int rowsCount) {
this.rowsCount.set(rowsCount);
}
public boolean isScrollOnOpen() {
return scrollOnOpen.get();
}
@ -417,6 +440,13 @@ public class MFXComboBox<T> extends MFXTextField implements MFXCombo<T> {
private static final StyleablePropertyFactory<MFXComboBox<?>> FACTORY = new StyleablePropertyFactory<>(MFXTextField.getClassCssMetaData());
private static final List<CssMetaData<? extends Styleable, ?>> cssMetaDataList;
private static final CssMetaData<MFXComboBox<?>, Number> ROWS_COUNT =
FACTORY.createSizeCssMetaData(
"-mfx-rows-count",
MFXComboBox::rowsCountProperty,
10
);
private static final CssMetaData<MFXComboBox<?>, Boolean> SCROLL_ON_OPEN =
FACTORY.createBooleanCssMetaData(
"-mfx-scroll-on-open",
@ -427,7 +457,7 @@ public class MFXComboBox<T> extends MFXTextField implements MFXCombo<T> {
static {
cssMetaDataList = StyleablePropertiesUtils.cssMetaDataList(
MFXTextField.getClassCssMetaData(),
SCROLL_ON_OPEN
ROWS_COUNT, SCROLL_ON_OPEN
);
}
}

View File

@ -23,6 +23,9 @@ import io.github.palexdev.materialfx.selection.ComboBoxSelectionModel;
import io.github.palexdev.materialfx.utils.AnimationUtils;
import io.github.palexdev.virtualizedfx.cell.Cell;
import io.github.palexdev.virtualizedfx.flow.simple.SimpleVirtualFlow;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
@ -50,6 +53,8 @@ public class MFXComboBoxSkin<T> extends MFXTextFieldSkin {
//================================================================================
protected final MFXPopup popup;
private EventHandler<MouseEvent> popupManager;
protected final BooleanProperty vfInitialized = new SimpleBooleanProperty(false);
protected SimpleVirtualFlow<T, Cell<T>> virtualFlow;
//================================================================================
@ -258,6 +263,16 @@ public class MFXComboBoxSkin<T> extends MFXTextFieldSkin {
};
virtualFlow.cellFactoryProperty().bind(comboBox.cellFactoryProperty());
virtualFlow.prefWidthProperty().bind(comboBox.widthProperty());
Runnable createBinding = () ->
virtualFlow.prefHeightProperty().bind(Bindings.createDoubleBinding(
() -> Math.min(comboBox.getRowsCount(), comboBox.getItems().size()) * virtualFlow.getCellHeight(),
comboBox.rowsCountProperty(), comboBox.getItems(), virtualFlow.cellFactoryProperty(), vfInitialized
));
virtualFlow.itemsProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) createBinding.run();
});
createBinding.run();
}
return virtualFlow;
}
@ -274,6 +289,14 @@ public class MFXComboBoxSkin<T> extends MFXTextFieldSkin {
//================================================================================
// Overridden Methods
//================================================================================
@Override
protected void layoutChildren(double x, double y, double w, double h) {
super.layoutChildren(x, y, w, h);
if (virtualFlow != null && !vfInitialized.get() && virtualFlow.getCellHeight() != 0)
vfInitialized.set(true);
}
@Override
public void dispose() {
super.dispose();

View File

@ -22,10 +22,9 @@ import io.github.palexdev.materialfx.collections.TransformableList;
import io.github.palexdev.materialfx.controls.BoundTextField;
import io.github.palexdev.materialfx.controls.MFXFilterComboBox;
import io.github.palexdev.materialfx.controls.MFXTextField;
import io.github.palexdev.materialfx.controls.cell.MFXFilterComboBoxCell;
import io.github.palexdev.materialfx.i18n.I18N;
import io.github.palexdev.virtualizedfx.cell.Cell;
import io.github.palexdev.virtualizedfx.flow.simple.SimpleVirtualFlow;
import javafx.beans.binding.Bindings;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
@ -114,7 +113,7 @@ public class MFXFilterComboBoxSkin<T> extends MFXComboBoxSkin<T> {
searchField.textProperty().bindBidirectional(comboBox.searchTextProperty());
searchField.setMaxWidth(Double.MAX_VALUE);
SimpleVirtualFlow<T, Cell<T>> virtualFlow = new SimpleVirtualFlow<>(
virtualFlow = new SimpleVirtualFlow<>(
filterList,
comboBox.getCellFactory(),
Orientation.VERTICAL
@ -127,6 +126,16 @@ public class MFXFilterComboBoxSkin<T> extends MFXComboBoxSkin<T> {
}
});
Runnable createBinding = () ->
virtualFlow.minHeightProperty().bind(Bindings.createDoubleBinding(
() -> Math.min(comboBox.getRowsCount(), comboBox.getItems().size()) * virtualFlow.getCellHeight(),
comboBox.rowsCountProperty(), comboBox.getItems(), virtualFlow.cellFactoryProperty(), vfInitialized
));
virtualFlow.itemsProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) createBinding.run();
});
createBinding.run();
VBox container = new VBox(10, searchField, virtualFlow);
container.getStyleClass().add("search-container");
container.setAlignment(Pos.TOP_CENTER);