From 1afd7a2226f437b74964fadce8b0123ef1142d8d Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 26 Dec 2022 15:31:46 -0300 Subject: [PATCH 01/12] refactor(demo): avoid use of deprecated constructor --- .../com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java | 5 +++-- .../vaadin/addons/twincolgrid/DoubleClickDemo.java | 2 +- .../vaadin/addons/twincolgrid/FilterableDemo.java | 3 ++- .../vaadin/addons/twincolgrid/OrientationDemo.java | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java index 6f6fd09..41b46d2 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java @@ -47,8 +47,7 @@ public BoundDemo() { // Binded final TwinColGrid twinColGrid = - new TwinColGrid<>( - availableBooks, "TwinColGrid demo with Binder and row select without checkbox") + new TwinColGrid<>(availableBooks) .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") @@ -57,6 +56,8 @@ public BoundDemo() { .withSizeFull() .selectRowOnClick(); + twinColGrid.setCaption("TwinColGrid demo with Binder and row select without checkbox"); + final Binder binder = new Binder<>(); binder.forField(twinColGrid.asList()).asRequired().bind(Library::getBooks, Library::setBooks); binder.setBean(library); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java index e6bc74f..3617945 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java @@ -43,7 +43,7 @@ public DoubleClickDemo() { initializeData(); final TwinColGrid twinColGrid = - new TwinColGrid<>(availableBooks, null) + new TwinColGrid<>(availableBooks) .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java index 779dae3..e450f6b 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java @@ -42,13 +42,14 @@ public FilterableDemo() { initializeData(); final TwinColGrid twinColGrid = - new TwinColGrid<>(availableBooks, "TwinColGrid demo with filtering support") + new TwinColGrid<>(availableBooks) .addFilterableColumn(Book::getIsbn, Book::getIsbn, "ISBN", "ISBN Filter", true) .addFilterableColumn(Book::getTitle, "Title", "Title filter", false) .withAvailableGridCaption("Available books") .withSelectionGridCaption("Added books") .withoutAddAllButton() .withSizeFull(); + twinColGrid.setCaption("TwinColGrid demo with filtering support"); twinColGrid.setValue(selectedBooks); add(twinColGrid); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java index c8b4a01..625efa6 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java @@ -45,7 +45,7 @@ public OrientationDemo() { initializeData(); final TwinColGrid twinColGrid = - new TwinColGrid<>(availableBooks, null) + new TwinColGrid<>(availableBooks) .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") From 81fa3863767a19fff4a4566c8ae90ba1ae5b3177 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 20 Oct 2022 16:34:41 -0300 Subject: [PATCH 02/12] feat!: remove deprecated methods Close #108 --- .../addons/twincolgrid/LegacyTwinColGrid.java | 283 ++++++++++++++++++ .../addons/twincolgrid/TwinColGrid.java | 207 +------------ 2 files changed, 285 insertions(+), 205 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java new file mode 100644 index 0000000..22ae1f6 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java @@ -0,0 +1,283 @@ +package com.flowingcode.vaadin.addons.twincolgrid; + +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.data.provider.ListDataProvider; +import com.vaadin.flow.data.selection.SelectionListener; +import java.util.Collection; +import java.util.function.Supplier; +import lombok.NonNull; + +/** Implementation of {@code TwinColGrid} with deprecated methods from version 2.9.0. */ +@SuppressWarnings("serial") +@Deprecated +public class LegacyTwinColGrid extends TwinColGrid { + + /** @deprecated Use getAvailableGrid() */ + @Deprecated protected final Grid leftGrid; + + /** @deprecated Use getSelectionGrid() */ + @Deprecated protected final Grid rightGrid; + + /** @deprecated Use getAvailableGrid().getDataProvider() */ + @Deprecated protected ListDataProvider leftGridDataProvider; + + /** @deprecated Use getSelectionGrid().getDataProvider() */ + @Deprecated protected ListDataProvider rightGridDataProvider; + + /** Constructs a new TwinColGrid with an empty {@link ListDataProvider}. */ + @SuppressWarnings("unchecked") + public LegacyTwinColGrid() { + super(); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new empty TwinColGrid, using the specified supplier for instantiating both grids. + * + * @param gridSupplier a supplier for instantiating both grids + */ + @SuppressWarnings("unchecked") + public LegacyTwinColGrid(Supplier> gridSupplier) { + super(gridSupplier); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new empty TwinColGrid, using the specified grids for each side. + * + * @param availableGrid the grid that contains the available items + * @param selectionGrid the grid that contains the selected items + */ + @SuppressWarnings("unchecked") + public LegacyTwinColGrid(@NonNull Grid availableGrid, @NonNull Grid selectionGrid) { + super(availableGrid, selectionGrid); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new empty TwinColGrid with caption + * + * @param caption the component caption + * @deprecated Use {@link TwinColGrid#TwinColGrid()} and {{@link #setCaption(String)} + */ + @Deprecated + @SuppressWarnings("unchecked") + public LegacyTwinColGrid(String caption) { + super(Grid::new); + setCaption(caption); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new TwinColGrid with data provider for options. + * + * @param dataProvider the data provider, not {@code null} + * @param caption the component caption + * @deprecated Use {@link #TwinColGrid()} and {@link #setDataProvider(ListDataProvider)}, {@link + * #setCaption(String)} + */ + @Deprecated + @SuppressWarnings("unchecked") + public LegacyTwinColGrid(final ListDataProvider dataProvider, String caption) { + super(Grid::new); + setDataProvider(dataProvider); + setCaption(caption); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new empty TwinColGrid, using the specified supplier for instantiating both grids. + * + * @param caption the component caption + * @param gridSupplier a supplier for instantiating both grids + * @deprecated Use {@link TwinColGrid#TwinColGrid(Supplier)} and {@link #setCaption(String)} + */ + @Deprecated + @SuppressWarnings("unchecked") + public LegacyTwinColGrid(String caption, Supplier> gridSupplier) { + super(gridSupplier.get(), gridSupplier.get()); + setCaption(caption); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new empty TwinColGrid, using the specified grids for each side. + * + * @param caption the component caption + * @param availableGrid the grid that contains the available items + * @param selectionGrid the grid that contains the selected items + * @deprecated Use {@link TwinColGrid#TwinColGrid(Grid, Grid)} and {@link #setCaption(String)} + */ + @Deprecated + @SuppressWarnings("unchecked") + public LegacyTwinColGrid( + String caption, @NonNull Grid availableGrid, @NonNull Grid selectionGrid) { + super(availableGrid, selectionGrid); + setCaption(caption); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** + * Constructs a new TwinColGrid with caption and the given options. + * + * @param caption the caption to set, can be {@code null} + * @param options the options, cannot be {@code null} + * @deprecated Use {@link #TwinColGrid(Collection)} and {{@link #setCaption(String)} + */ + @Deprecated + @SuppressWarnings("unchecked") + public LegacyTwinColGrid(final Collection options, final String caption) { + super(options); + setCaption(caption); + leftGrid = getAvailableGrid(); + rightGrid = getSelectionGrid(); + leftGridDataProvider = (ListDataProvider) getAvailableGrid().getDataProvider(); + rightGridDataProvider = (ListDataProvider) getSelectionGrid().getDataProvider(); + } + + /** @deprecated Use {@code getAvailableGrid().setClassName(classname)} */ + @Deprecated + public void setLeftGridClassName(String classname) { + getAvailableGrid().setClassName(classname); + } + + /** @deprecated Use {@code getAvailableGrid().addClassName(classname)} */ + @Deprecated + public void addLeftGridClassName(String classname) { + getAvailableGrid().addClassName(classname); + } + + /** @deprecated Use {@code getAvailableGrid().removeClassName(classname)} */ + @Deprecated + public void removeLeftGridClassName(String classname) { + getAvailableGrid().removeClassName(classname); + } + + /** @deprecated Use {@code getSelectionGrid().setClassName(classname)} */ + @Deprecated + public void setRightGridClassName(String classname) { + getSelectionGrid().setClassName(classname); + } + + /** @deprecated Use {@code getSelectionGrid().addClassName(classname)} */ + @Deprecated + public void addRightGridClassName(String classname) { + getSelectionGrid().addClassName(classname); + } + + /** @deprecated Use {@code getSelectionGrid().removeClassName(classname)} */ + @Deprecated + public void removeRightGridClassName(String classname) { + getSelectionGrid().removeClassName(classname); + } + + /** + * Sets the text shown above the grid with the available items. {@code null} clears the caption. + * + * @param caption The text to show, {@code null} to clear + * @return this instance + * @deprecated Use {@link #withAvailableGridCaption(String)} + */ + @Deprecated + public LegacyTwinColGrid withRightColumnCaption(final String caption) { + withSelectionGridCaption(caption); + return this; + } + + /** + * Sets the text shown above the grid with the available items. {@code null} clears the caption. + * + * @param caption The text to show, {@code null} to clear + * @return this instance + * @deprecated Use {@link #withSelectionGridCaption(String)} + */ + @Deprecated + public LegacyTwinColGrid withLeftColumnCaption(final String caption) { + withAvailableGridCaption(caption); + return this; + } + + /** + * Returns the text shown above the right column. + * + * @return The text shown or {@code null} if not set. + * @deprecated Use {@link #getSelectionGridCaption()} + */ + @Deprecated + public String getRightColumnCaption() { + return getSelectionGridCaption(); + } + + /** + * Returns the text shown above the left column. + * + * @return The text shown or {@code null} if not set. + * @deprecated Use {@link #getAvailableGridCaption()} + */ + @Deprecated + public String getLeftColumnCaption() { + return getAvailableGridCaption(); + } + + /** @deprecated Use {@code getAvailableGrid().addSelectionListener(listener);} */ + @Deprecated + public void addLeftGridSelectionListener(SelectionListener, T> listener) { + getAvailableGrid().addSelectionListener(listener); + } + + /** @deprecated Use {@code getSelectionGrid().addSelectionListener(listener);} */ + @Deprecated + public void addRightGridSelectionListener(SelectionListener, T> listener) { + getSelectionGrid().addSelectionListener(listener); + } + + /** + * Return the left grid component. + * + * @deprecated Use {@link #getAvailableGrid()}. Depending on the orientation, the "left grid" may + * not be located at the left side. + */ + @Deprecated + public Grid getLeftGrid() { + return leftGrid; + } + + /** + * Return the right grid component. + * + * @deprecated Use {@link #getSelectionGrid()}. Depending on the orientation, the "right grid" may + * not be located at the right side. + */ + @Deprecated + public Grid getRightGrid() { + return rightGrid; + } + + @Override + protected void setDataProvider(ListDataProvider dataProvider) { + leftGridDataProvider = dataProvider; + super.setDataProvider(dataProvider); + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index 2045bdc..255e5e4 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -47,7 +47,6 @@ import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.data.provider.Query; import com.vaadin.flow.data.renderer.TextRenderer; -import com.vaadin.flow.data.selection.SelectionListener; import com.vaadin.flow.data.value.ValueChangeMode; import com.vaadin.flow.function.SerializableComparator; import com.vaadin.flow.function.SerializableFunction; @@ -124,18 +123,6 @@ public enum Orientation { private final TwinColModel selection; - /** @deprecated Use getAvailableGrid() */ - @Deprecated protected final Grid leftGrid; - - /** @deprecated Use getSelectionGrid() */ - @Deprecated protected final Grid rightGrid; - - /** @deprecated Use getAvailableGrid().getDataProvider() */ - @Deprecated protected ListDataProvider leftGridDataProvider; - - /** @deprecated Use getSelectionGrid().getDataProvider() */ - @Deprecated protected ListDataProvider rightGridDataProvider; - private Label captionLabel; private final Button addAllButton = createActionButton(); @@ -167,46 +154,6 @@ public TwinColGrid() { this(Grid::new); } - /** - * Constructs a new empty TwinColGrid with caption - * - * @param caption the component caption - * @deprecated Use {@link TwinColGrid#TwinColGrid()} and {{@link #setCaption(String)} - */ - @Deprecated - public TwinColGrid(String caption) { - this(Grid::new); - setCaption(caption); - } - - /** - * Constructs a new TwinColGrid with data provider for options. - * - * @param dataProvider the data provider, not {@code null} - * @param caption the component caption - * @deprecated Use {@link #TwinColGrid()} and {@link #setDataProvider(ListDataProvider)}, - * {@link #setCaption(String)} - */ - @Deprecated - public TwinColGrid(final ListDataProvider dataProvider, String caption) { - this(Grid::new); - setDataProvider(dataProvider); - setCaption(caption); - } - - /** - * Constructs a new empty TwinColGrid, using the specified supplier for instantiating both grids. - * - * @param caption the component caption - * @param gridSupplier a supplier for instantiating both grids - * @deprecated Use {@link TwinColGrid#TwinColGrid(Supplier)} and {@link #setCaption(String)} - */ - @Deprecated - public TwinColGrid(String caption, Supplier> gridSupplier) { - this(gridSupplier.get(), gridSupplier.get()); - setCaption(caption); - } - /** * Constructs a new empty TwinColGrid, using the specified supplier for instantiating both grids. * @@ -216,22 +163,6 @@ public TwinColGrid(Supplier> gridSupplier) { this(gridSupplier.get(), gridSupplier.get()); } - /** - * Constructs a new empty TwinColGrid, using the specified grids for each side. - * - * @param caption the component caption - * @param availableGrid the grid that contains the available items - * @param selectionGrid the grid that contains the selected items - * - * @deprecated Use {@link TwinColGrid#TwinColGrid(Grid, Grid)} and {@link #setCaption(String)} - */ - @Deprecated - public TwinColGrid(String caption, @NonNull Grid availableGrid, - @NonNull Grid selectionGrid) { - this(availableGrid, selectionGrid); - setCaption(caption); - } - /** * Constructs a new empty TwinColGrid, using the specified grids for each side. * @@ -247,16 +178,13 @@ public TwinColGrid(@NonNull Grid availableGrid, @NonNull Grid selectionGri available = new TwinColModel<>(availableGrid, "twincol-grid-available"); selection = new TwinColModel<>(selectionGrid, "twincol-grid-selection"); - leftGrid = available.grid; - rightGrid = selection.grid; - setClassName("twincol-grid"); setMargin(false); setPadding(false); setDataProvider(emptyDataProvider()); - rightGridDataProvider = DataProvider.ofCollection(new LinkedHashSet<>()); + ListDataProvider rightGridDataProvider = DataProvider.ofCollection(new LinkedHashSet<>()); getSelectionGrid().setDataProvider(rightGridDataProvider); getAvailableGrid().setWidth("100%"); @@ -448,28 +376,6 @@ public Grid getSelectionGrid() { return selection.grid; } - /** - * Return the left grid component. - * - * @deprecated Use {@link #getAvailableGrid()}. Depending on the orientation, the "left grid" may - * not be located at the left side. - */ - @Deprecated - public Grid getLeftGrid() { - return leftGrid; - } - - /** - * Return the right grid component. - * - * @deprecated Use {@link #getSelectionGrid()}. Depending on the orientation, the "right grid" may - * not be located at the right side. - */ - @Deprecated - public Grid getRightGrid() { - return rightGrid; - } - private void forEachSide(Consumer> consumer) { consumer.accept(available); consumer.accept(selection); @@ -488,48 +394,11 @@ public void setItems(Stream items) { setDataProvider(DataProvider.fromStream(items)); } - /** @deprecated Use {@code getAvailableGrid().setClassName(classname)} */ - @Deprecated - public void setLeftGridClassName(String classname) { - getAvailableGrid().setClassName(classname); - } - - /** @deprecated Use {@code getAvailableGrid().addClassName(classname)} */ - @Deprecated - public void addLeftGridClassName(String classname) { - getAvailableGrid().addClassName(classname); - } - - /** @deprecated Use {@code getAvailableGrid().removeClassName(classname)} */ - @Deprecated - public void removeLeftGridClassName(String classname) { - getAvailableGrid().removeClassName(classname); - } - - /** @deprecated Use {@code getSelectionGrid().setClassName(classname)} */ - @Deprecated - public void setRightGridClassName(String classname) { - getSelectionGrid().setClassName(classname); - } - - /** @deprecated Use {@code getSelectionGrid().addClassName(classname)} */ - @Deprecated - public void addRightGridClassName(String classname) { - getSelectionGrid().addClassName(classname); - } - - /** @deprecated Use {@code getSelectionGrid().removeClassName(classname)} */ - @Deprecated - public void removeRightGridClassName(String classname) { - getSelectionGrid().removeClassName(classname); - } - public void clearAll() { updateSelection(new HashSet<>(), new HashSet<>(selection.getItems()), false); } - private void setDataProvider(ListDataProvider dataProvider) { - leftGridDataProvider = dataProvider; + protected void setDataProvider(ListDataProvider dataProvider) { getAvailableGrid().setDataProvider(dataProvider); if (selection.getDataProvider() != null) { selection.getItems().clear(); @@ -547,20 +416,6 @@ public TwinColGrid(final Collection options) { setDataProvider(DataProvider.ofCollection(new LinkedHashSet<>(options))); } - /** - * Constructs a new TwinColGrid with caption and the given options. - * - * @param caption the caption to set, can be {@code null} - * @param options the options, cannot be {@code null} - * - * @deprecated Use {@link #TwinColGrid(Collection)} and {{@link #setCaption(String)} - */ - @Deprecated - public TwinColGrid(final Collection options, final String caption) { - this(options); - setCaption(caption); - } - /** * Sets the text shown above the grid with the available items. {@code null} clears the caption. * @@ -587,30 +442,6 @@ public TwinColGrid withSelectionGridCaption(final String caption) { return this; } - /** - * Sets the text shown above the grid with the available items. {@code null} clears the caption. - * - * @param caption The text to show, {@code null} to clear - * @return this instance - * @deprecated Use {@link #withAvailableGridCaption(String)} - */ - @Deprecated - public TwinColGrid withRightColumnCaption(final String caption) { - return withSelectionGridCaption(caption); - } - - /** - * Sets the text shown above the grid with the available items. {@code null} clears the caption. - * - * @param caption The text to show, {@code null} to clear - * @return this instance - * @deprecated Use {@link #withSelectionGridCaption(String)} - */ - @Deprecated - public TwinColGrid withLeftColumnCaption(final String caption) { - return withAvailableGridCaption(caption); - } - /** * Adds a new text column to this {@link Grid} with a value provider. The column will use a {@link * TextRenderer}. The value is converted to a String using the provided {@code @@ -742,28 +573,6 @@ public String getSelectionGridCaption() { return selection.columnLabel.getText(); } - /** - * Returns the text shown above the right column. - * - * @return The text shown or {@code null} if not set. - * @deprecated Use {@link #getSelectionGridCaption()} - */ - @Deprecated - public String getRightColumnCaption() { - return getSelectionGridCaption(); - } - - /** - * Returns the text shown above the left column. - * - * @return The text shown or {@code null} if not set. - * @deprecated Use {@link #getAvailableGridCaption()} - */ - @Deprecated - public String getLeftColumnCaption() { - return getAvailableGridCaption(); - } - /** * Set {@code value} to grid * @@ -975,18 +784,6 @@ public boolean isSelectionGridReorderingAllowed() { return selection.allowReordering; } - /** @deprecated Use {@code getAvailableGrid().addSelectionListener(listener);} */ - @Deprecated - public void addLeftGridSelectionListener(SelectionListener, T> listener) { - getAvailableGrid().addSelectionListener(listener); - } - - /** @deprecated Use {@code getSelectionGrid().addSelectionListener(listener);} */ - @Deprecated - public void addRightGridSelectionListener(SelectionListener, T> listener) { - getSelectionGrid().addSelectionListener(listener); - } - public TwinColGrid addFilterableColumn( final ItemLabelGenerator itemLabelGenerator, SerializableFunction filterableValue, From 64c12b2de2aa8ef52091576f073004fcde974094 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 20 Oct 2022 16:14:57 -0300 Subject: [PATCH 03/12] feat!: enable move items by doubleclick by default --- .../flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java | 5 +++++ .../vaadin/addons/twincolgrid/DoubleClickDemo.java | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index 255e5e4..dd12281 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -223,10 +223,15 @@ public TwinColGrid(@NonNull Grid availableGrid, @NonNull Grid selectionGri side.layout.setSpacing(false); }); + initMoveItemsByDoubleClick(); add(createContainerLayout()); setSizeUndefined(); } + @SuppressWarnings("deprecation") + private void initMoveItemsByDoubleClick() { + setMoveItemsByDoubleClick(!(this instanceof LegacyTwinColGrid)); + } /** * Sets the component caption. diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java index 3617945..d693885 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java @@ -51,7 +51,6 @@ public DoubleClickDemo() { .withSizeFull() .selectRowOnClick(); twinColGrid.setValue(selectedBooks); - twinColGrid.setMoveItemsByDoubleClick(true); add(new Span("Move items by double click"), twinColGrid); setSizeFull(); From b63320c204ea20c7040dc71262e2762ef1f7381f Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 20 Oct 2022 16:37:13 -0300 Subject: [PATCH 04/12] style: apply code formatting --- .../addons/twincolgrid/TwinColGrid.java | 188 ++++++++++-------- .../twincolgrid/TwinColGridListAdapter.java | 32 +-- .../vaadin/addons/twincolgrid/BoundDemo.java | 27 ++- .../addons/twincolgrid/DragAndDropDemo.java | 38 ++-- .../addons/twincolgrid/FilterableDemo.java | 6 +- 5 files changed, 168 insertions(+), 123 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index dd12281..ccda964 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -192,22 +192,31 @@ public TwinColGrid(@NonNull Grid availableGrid, @NonNull Grid selectionGri addAllButton.addClickListener( e -> { - List filteredItems = available.getDataProvider().withConfigurableFilter() - .fetch(new Query<>()).collect(Collectors.toList()); + List filteredItems = + available + .getDataProvider() + .withConfigurableFilter() + .fetch(new Query<>()) + .collect(Collectors.toList()); updateSelection(new LinkedHashSet<>(filteredItems), new HashSet<>(), true); }); addButton.addClickListener( e -> updateSelection( - new LinkedHashSet<>(getAvailableGrid().getSelectedItems()), new HashSet<>(), true)); + new LinkedHashSet<>(getAvailableGrid().getSelectedItems()), new HashSet<>(), true)); removeButton.addClickListener( e -> updateSelection(new HashSet<>(), getSelectionGrid().getSelectedItems(), true)); removeAllButton.addClickListener( e -> { - List filteredItems= selection.getDataProvider().withConfigurableFilter().fetch(new Query<>()).collect(Collectors.toList()); + List filteredItems = + selection + .getDataProvider() + .withConfigurableFilter() + .fetch(new Query<>()) + .collect(Collectors.toList()); updateSelection(new HashSet<>(), new HashSet<>(filteredItems), true); }); @@ -364,8 +373,7 @@ private VerticalLayout getVerticalButtonContainer() { private HorizontalLayout getHorizontalButtonContainer() { HorizontalLayout hButtonContainer = - new HorizontalLayout( - addAllButton, addButton, removeButton, removeAllButton); + new HorizontalLayout(addAllButton, addButton, removeButton, removeAllButton); hButtonContainer.setPadding(false); hButtonContainer.setSizeUndefined(); return hButtonContainer; @@ -477,8 +485,9 @@ public TwinColGrid addSortableColumn( final ItemLabelGenerator itemLabelGenerator, Comparator comparator, final String header) { - forEachGrid(grid -> grid - .addColumn(new TextRenderer<>(itemLabelGenerator)) + forEachGrid( + grid -> + grid.addColumn(new TextRenderer<>(itemLabelGenerator)) .setHeader(header) .setComparator(comparator) .setSortable(true)); @@ -501,8 +510,9 @@ public TwinColGrid addSortableColumn( Comparator comparator, final String header, final String key) { - forEachGrid(grid -> grid - .addColumn(new TextRenderer<>(itemLabelGenerator)) + forEachGrid( + grid -> + grid.addColumn(new TextRenderer<>(itemLabelGenerator)) .setHeader(header) .setComparator(comparator) .setSortable(true) @@ -603,8 +613,8 @@ public void setValue(final Set value) { */ @Override public Set getValue() { - return Collections - .unmodifiableSet(collectValue(Collectors.>toCollection(LinkedHashSet::new))); + return Collections.unmodifiableSet( + collectValue(Collectors.>toCollection(LinkedHashSet::new))); } /** @@ -624,15 +634,17 @@ C collectValue(Collector collector) { private static SerializableComparator createSortingComparator(Grid grid) { // protected method copied from Grid::createSortingComparator - BinaryOperator> operator = (comparator1, comparator2) -> { - /* - * thenComparing is defined to return a serializable comparator as long as both original - * comparators are also serializable - */ - return comparator1.thenComparing(comparator2)::compare; - }; + BinaryOperator> operator = + (comparator1, comparator2) -> { + /* + * thenComparing is defined to return a serializable comparator as long as both original + * comparators are also serializable + */ + return comparator1.thenComparing(comparator2)::compare; + }; return grid.getSortOrder().stream() - .map(order -> order.getSorted().getComparator(order.getDirection())).reduce(operator) + .map(order -> order.getSorted().getComparator(order.getDirection())) + .reduce(operator) .orElse(null); } @@ -644,7 +656,8 @@ public Registration addValueChangeListener( .addDataProviderListener( e -> { ComponentValueChangeEvent, Set> e2 = - new ComponentValueChangeEvent<>(TwinColGrid.this, TwinColGrid.this, null, isFromClient); + new ComponentValueChangeEvent<>( + TwinColGrid.this, TwinColGrid.this, null, isFromClient); listener.valueChanged(e2); }); } @@ -674,7 +687,8 @@ public void setRequiredIndicatorVisible(boolean requiredIndicatorVisible) { getElement().setAttribute("required", requiredIndicatorVisible); } - private void updateSelection(final Set addedItems, final Set removedItems, boolean isFromClient) { + private void updateSelection( + final Set addedItems, final Set removedItems, boolean isFromClient) { this.isFromClient = isFromClient; available.getItems().addAll(removedItems); available.getItems().removeAll(addedItems); @@ -682,9 +696,10 @@ private void updateSelection(final Set addedItems, final Set removedItems, selection.getItems().addAll(addedItems); selection.getItems().removeAll(removedItems); - forEachGrid(grid -> { - grid.getDataProvider().refreshAll(); - grid.getSelectionModel().deselectAll(); + forEachGrid( + grid -> { + grid.getDataProvider().refreshAll(); + grid.getSelectionModel().deselectAll(); }); } @@ -702,8 +717,8 @@ private void configDragAndDrop( draggedItems.addAll(event.getDraggedItems()); } - sourceModel.grid - .setDropMode(sourceModel.isReorderingEnabled() ? GridDropMode.BETWEEN : null); + sourceModel.grid.setDropMode( + sourceModel.isReorderingEnabled() ? GridDropMode.BETWEEN : null); targetModel.grid.setDropMode( targetModel.isReorderingEnabled() ? GridDropMode.BETWEEN : GridDropMode.ON_GRID); }); @@ -740,25 +755,31 @@ private void configDragAndDrop( } }); - sourceModel.grid.addDropListener(event -> { - event.getDropTargetItem().ifPresent(dropOverItem -> { - if (sourceModel.isReorderingEnabled() - && event.getSource() == draggedGrid - && !draggedItems.contains(dropOverItem) - && !draggedItems.isEmpty()) { - isFromClient = true; - sourceModel.getItems().removeAll(draggedItems); - addItems(sourceModel, draggedItems, dropOverItem, event.getDropLocation()); - draggedItems.clear(); - draggedGrid = null; - } - }); - }); - + sourceModel.grid.addDropListener( + event -> { + event + .getDropTargetItem() + .ifPresent( + dropOverItem -> { + if (sourceModel.isReorderingEnabled() + && event.getSource() == draggedGrid + && !draggedItems.contains(dropOverItem) + && !draggedItems.isEmpty()) { + isFromClient = true; + sourceModel.getItems().removeAll(draggedItems); + addItems(sourceModel, draggedItems, dropOverItem, event.getDropLocation()); + draggedItems.clear(); + draggedGrid = null; + } + }); + }); } - private void addItems(TwinColModel model, Collection draggedItems, - T dropOverItem, GridDropLocation dropLocation) { + private void addItems( + TwinColModel model, + Collection draggedItems, + T dropOverItem, + GridDropLocation dropLocation) { if (dropOverItem != null) { Collection collection = model.getItems(); List list = new ArrayList<>(collection); @@ -794,7 +815,8 @@ public TwinColGrid addFilterableColumn( SerializableFunction filterableValue, final String header, String filterPlaceholder, - boolean enableClearButton, String key) { + boolean enableClearButton, + String key) { forEachSide( side -> { Column column = @@ -831,33 +853,41 @@ public TwinColGrid addFilterableColumn( final String header, String filterPlaceholder, boolean enableClearButton) { - return addFilterableColumn(itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, - enableClearButton, null); + return addFilterableColumn( + itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, enableClearButton, null); } - public TwinColGrid addFilterableColumn(ItemLabelGenerator itemLabelGenerator, - SerializableFunction filterableValue, String header, String filterPlaceholder, + public TwinColGrid addFilterableColumn( + ItemLabelGenerator itemLabelGenerator, + SerializableFunction filterableValue, + String header, + String filterPlaceholder, boolean enableClearButton) { - return addFilterableColumn(itemLabelGenerator, filterableValue, header, filterPlaceholder, - enableClearButton, null); + return addFilterableColumn( + itemLabelGenerator, filterableValue, header, filterPlaceholder, enableClearButton, null); } - public TwinColGrid addFilterableColumn(ItemLabelGenerator itemLabelGenerator, String header, - String filterPlaceholder, boolean enableClearButton, String key) { - return addFilterableColumn(itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, - enableClearButton, key); + public TwinColGrid addFilterableColumn( + ItemLabelGenerator itemLabelGenerator, + String header, + String filterPlaceholder, + boolean enableClearButton, + String key) { + return addFilterableColumn( + itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, enableClearButton, key); } public TwinColGrid selectRowOnClick() { - forEachGrid(grid -> { - grid.addClassName("hide-selector-col"); + forEachGrid( + grid -> { + grid.addClassName("hide-selector-col"); - grid.addItemClickListener( + grid.addItemClickListener( c -> { - if (grid.getSelectedItems().contains(c.getItem())) { - grid.deselect(c.getItem()); + if (grid.getSelectedItems().contains(c.getItem())) { + grid.deselect(c.getItem()); } else { - grid.select(c.getItem()); + grid.select(c.getItem()); } }); }); @@ -879,9 +909,7 @@ private Button createActionButton() { return button; } - /** - * Return whether autoResize is set or not. - */ + /** Return whether autoResize is set or not. */ public boolean isAutoResize() { return autoResize; } @@ -908,23 +936,26 @@ public void setAutoResize(boolean autoResize) { * @param value if true, a a doubleclick event will immediately move an item to the other grid */ public void setMoveItemsByDoubleClick(boolean value) { - forEachSide(side -> { - if (value && side.moveItemsByDoubleClick == null) { - side.moveItemsByDoubleClick = side.grid.addItemDoubleClickListener(ev -> { - Set item = Collections.singleton(ev.getItem()); - if (side == available) { - updateSelection(item, Collections.emptySet(), true); + forEachSide( + side -> { + if (value && side.moveItemsByDoubleClick == null) { + side.moveItemsByDoubleClick = + side.grid.addItemDoubleClickListener( + ev -> { + Set item = Collections.singleton(ev.getItem()); + if (side == available) { + updateSelection(item, Collections.emptySet(), true); + } + if (side == selection) { + updateSelection(Collections.emptySet(), item, true); + } + }); } - if (side == selection) { - updateSelection(Collections.emptySet(), item, true); + if (!value && side.moveItemsByDoubleClick != null) { + side.moveItemsByDoubleClick.remove(); + side.moveItemsByDoubleClick = null; } }); - } - if (!value && side.moveItemsByDoubleClick != null) { - side.moveItemsByDoubleClick.remove(); - side.moveItemsByDoubleClick = null; - } - }); } @ClientCallable @@ -935,5 +966,4 @@ private void updateOrientationOnResize(int width, int height) { this.withOrientation(Orientation.HORIZONTAL); } } - } diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java index 053e415..068e60e 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java @@ -72,7 +72,6 @@ public HasValue> getHasValue() { public List getOldValue() { return null; } - } @NonNull @@ -95,20 +94,26 @@ public Registration addValueChangeListener( List registrations = new ArrayList<>(); - registrations.add(delegate.addValueChangeListener(ev -> { - List value = new ArrayList<>(ev.getValue()); - ValueChangeEvent> listEvent; - listEvent = new ValueChangeEventImpl(ev.isFromClient(), new ArrayList<>(value)); - listener.valueChanged(listEvent); - })); + registrations.add( + delegate.addValueChangeListener( + ev -> { + List value = new ArrayList<>(ev.getValue()); + ValueChangeEvent> listEvent; + listEvent = new ValueChangeEventImpl(ev.isFromClient(), new ArrayList<>(value)); + listener.valueChanged(listEvent); + })); // sorting the grid changes its value under List::equals - registrations.add(delegate.getSelectionGrid().addSortListener(ev -> { - List value = getValue(); - ValueChangeEvent> listEvent; - listEvent = new ValueChangeEventImpl(ev.isFromClient(), value); - listener.valueChanged(listEvent); - })); + registrations.add( + delegate + .getSelectionGrid() + .addSortListener( + ev -> { + List value = getValue(); + ValueChangeEvent> listEvent; + listEvent = new ValueChangeEventImpl(ev.isFromClient(), value); + listener.valueChanged(listEvent); + })); return () -> registrations.forEach(Registration::remove); } @@ -117,5 +122,4 @@ public Registration addValueChangeListener( public List getEmptyValue() { return Collections.emptyList(); } - } diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java index 41b46d2..48613fe 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java @@ -63,14 +63,22 @@ public BoundDemo() { binder.setBean(library); add(twinColGrid); - add(new Button("Get values", ev -> { - binder.getBean().getBooks() - .forEach(book -> Notification.show(book.getTitle(), 3000, Position.BOTTOM_START)); - })); + add( + new Button( + "Get values", + ev -> { + binder + .getBean() + .getBooks() + .forEach(book -> Notification.show(book.getTitle(), 3000, Position.BOTTOM_START)); + })); - add(new Button("Clear TwinColGrid", ev -> { - twinColGrid.clear(); - })); + add( + new Button( + "Clear TwinColGrid", + ev -> { + twinColGrid.clear(); + })); setSizeFull(); } @@ -79,11 +87,10 @@ private void initializeData() { selectedBooks.add(new Book("1478375108", "Vaadin Recipes")); selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 ")); - availableBooks.add(new Book("1478375108", "Vaadin Recipes")); availableBooks.add(new Book("9781849515221", "Learning Vaadin")); - availableBooks - .add(new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide")); + availableBooks.add( + new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide")); availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook")); availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision")); availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 ")); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java index ff6205c..6028d29 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java @@ -49,7 +49,8 @@ public class DragAndDropDemo extends VerticalLayout { public DragAndDropDemo() { initializeData(); - twinColGrid = new TwinColGrid<>(availableBooks) + twinColGrid = + new TwinColGrid<>(availableBooks) .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") @@ -64,8 +65,12 @@ public DragAndDropDemo() { twinColGrid.setValue(selectedBooks); final Label countLabel = new Label("Selected items in left grid: 0"); - twinColGrid.getAvailableGrid().addSelectionListener( - e -> countLabel.setText("Selected items in left grid: " + e.getAllSelectedItems().size())); + twinColGrid + .getAvailableGrid() + .addSelectionListener( + e -> + countLabel.setText( + "Selected items in left grid: " + e.getAllSelectedItems().size())); twinColGrid.addValueChangeListener(e -> countLabel.setText("Selected items in left grid: 0")); add(twinColGrid, countLabel); @@ -78,11 +83,10 @@ private void initializeData() { selectedBooks.add(new Book("1478375108", "Vaadin Recipes")); selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 ")); - availableBooks.add(new Book("1478375108", "Vaadin Recipes")); availableBooks.add(new Book("9781849515221", "Learning Vaadin")); - availableBooks - .add(new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide")); + availableBooks.add( + new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide")); availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook")); availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision")); availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 ")); @@ -95,16 +99,18 @@ private void addReorderingToggle() { Span description = new Span("(Reordering is disabled while the grid is sorted)"); description.setVisible(false); - SerializableRunnable refresh = () -> { - boolean sorted = !twinColGrid.getSelectionGrid().getSortOrder().isEmpty(); - boolean allowed = twinColGrid.isSelectionGridReorderingAllowed(); - description.setVisible(sorted && allowed); - }; - - checkbox.addValueChangeListener(ev -> { - twinColGrid.setSelectionGridReorderingAllowed(ev.getValue()); - refresh.run(); - }); + SerializableRunnable refresh = + () -> { + boolean sorted = !twinColGrid.getSelectionGrid().getSortOrder().isEmpty(); + boolean allowed = twinColGrid.isSelectionGridReorderingAllowed(); + description.setVisible(sorted && allowed); + }; + + checkbox.addValueChangeListener( + ev -> { + twinColGrid.setSelectionGridReorderingAllowed(ev.getValue()); + refresh.run(); + }); twinColGrid.getSelectionGrid().addSortListener(ev -> refresh.run()); add(new Div(checkbox, description)); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java index e450f6b..60cf525 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java @@ -60,16 +60,14 @@ private void initializeData() { selectedBooks.add(new Book("1478375108", "Vaadin Recipes")); selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 ")); - availableBooks.add(new Book("1478375108", "Vaadin Recipes")); availableBooks.add(new Book("9781849515221", "Learning Vaadin")); - availableBooks - .add(new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide")); + availableBooks.add( + new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide")); availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook")); availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision")); availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 ")); availableBooks.add(new Book("9529267533", "Book of Vaadin")); availableBooks.add(new Book("1782169776", "Learning Vaadin 7, Second Edition")); } - } From d7ebe64fb9a83a831f1f936a216c887d12e1d2cb Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 26 Dec 2022 15:26:14 -0300 Subject: [PATCH 05/12] feat: add TwinColumn helper --- .../addons/twincolgrid/TwinColGrid.java | 15 ++ .../vaadin/addons/twincolgrid/TwinColumn.java | 238 ++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColumn.java diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index ccda964..72574b5 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -455,6 +455,21 @@ public TwinColGrid withSelectionGridCaption(final String caption) { return this; } + /** + * Adds a column to each grids. Both columns will use a {@link TextRenderer} and the value + * will be converted to a String by using the provided {@code itemLabelGenerator}. + * + * @param itemLabelGenerator the value provider + * @return the pair of columns + */ + public TwinColumn addColumn(ItemLabelGenerator itemLabelGenerator) { + Column availableColumn = + getAvailableGrid().addColumn(new TextRenderer<>(itemLabelGenerator)); + Column selectionColumn = + getSelectionGrid().addColumn(new TextRenderer<>(itemLabelGenerator)); + return new TwinColumn<>(availableColumn, selectionColumn); + } + /** * Adds a new text column to this {@link Grid} with a value provider. The column will use a {@link * TextRenderer}. The value is converted to a String using the provided {@code diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColumn.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColumn.java new file mode 100644 index 0000000..8064d7a --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColumn.java @@ -0,0 +1,238 @@ +package com.flowingcode.vaadin.addons.twincolgrid; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.grid.Grid.Column; +import com.vaadin.flow.component.grid.SortOrderProvider; +import com.vaadin.flow.data.provider.QuerySortOrder; +import com.vaadin.flow.function.SerializableFunction; +import com.vaadin.flow.function.ValueProvider; +import java.util.Comparator; +import java.util.function.Supplier; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** Fluent helper object that delegates setters on both columns. */ +@RequiredArgsConstructor +public class TwinColumn { + + /** + * Returns the column in the grid with the available items. + * + * @return The column in the grid with the available items. + */ + @Getter + private final Column availableColumn; + + /** + * Returns the column in the grid with the selected items. + * + * @return The column in the grid with the selected items. + */ + @Getter + private final Column selectionColumn; + + /** + * Sets the width of the columns as a CSS-string. + * + * @see Column#setWidth(String) + * + * @param width the width to set both columns to, as a CSS-string, not {@code null} + * @return this instance, for method chaining + */ + public TwinColumn setWidth(String width) { + availableColumn.setWidth(width); + selectionColumn.setWidth(width); + return this; + } + + /** + * Sets the flex grow ratio for the columns. When set to 0, column width is fixed. + * + * @see Column#setFlexGrow(int) + * + * @param flexGrow the flex grow ratio + * @return this instance, for method chaining + */ + public TwinColumn setFlexGrow(int flexGrow) { + availableColumn.setFlexGrow(flexGrow); + selectionColumn.setFlexGrow(flexGrow); + return this; + } + + /** + * Enables or disables automatic width for the columns. + * + * @see Column#setAutoWidth(boolean) + * + * @param autoWidth whether to enable or disable automatic width on both columns + * @return this instance, for method chaining + */ + public TwinColumn setAutoWidth(boolean autoWidth) { + availableColumn.setAutoWidth(autoWidth); + selectionColumn.setAutoWidth(autoWidth); + return this; + } + + /** + * Sets the user-defined identifier to map the columns. + * + * @see Column#setKey(String) + * + * @param key the identifier key, can't be {@code null} + * @return this instance, for method chaining + */ + public TwinColumn setKey(String key) { + availableColumn.setKey(key); + selectionColumn.setKey(key); + return this; + } + + /** + * Sets a comparator to use with in-memory sorting with both columns. + * + * @see Column#setComparator(Comparator) + * + * @param comparator the comparator to use when sorting data in both columns + * @return this instance, for method chaining + */ + public TwinColumn setComparator(Comparator comparator) { + availableColumn.setComparator(comparator); + selectionColumn.setComparator(comparator); + return this; + } + + /** + * Sets a comparator to use with in-memory sorting with both columns based on the return type of + * the given {@link ValueProvider}. + * + * @see Column#setComparator(ValueProvider) + * + * @param the value of the column + * @param keyExtractor the value provider used to extract the {@link Comparable} sort key + * @return this instance, for method chaining + * @see Comparator#comparing(java.util.function.Function) + */ + public > TwinColumn setComparator( + ValueProvider keyExtractor) { + availableColumn.setComparator(keyExtractor); + selectionColumn.setComparator(keyExtractor); + return this; + } + + /** + * Sets strings describing back end properties to be used when sorting the columns. + * + * @see Column#setSortProperty(String...) + * + * @param properties the array of strings describing backend properties + * @return this instance, for method chaining + */ + public TwinColumn setSortProperty(String... properties) { + availableColumn.setSortProperty(properties); + selectionColumn.setSortProperty(properties); + return this; + } + + /** + * Sets the sort orders when sorting the columns. The sort order provider is a function which + * provides {@link QuerySortOrder} objects to describe how to sort by the columns. + * + * @see Column#setSortOrderProvider(SortOrderProvider) + * + * @param provider the function to use when generating sort orders with the given direction + * @return this instance, for method chaining + */ + public TwinColumn setSortOrderProvider(SortOrderProvider provider) { + availableColumn.setSortOrderProvider(provider); + selectionColumn.setSortOrderProvider(provider); + return this; + } + + /** + * Sets whether the user can sort the columns or not. + * + * @see Column#setSortable(boolean) + * + * @param sortable {@code true} if the columns can be sorted by the user; {@code false} if not + * @return this instance, for method chaining + */ + public TwinColumn setSortable(boolean sortable) { + availableColumn.setSortable(sortable); + selectionColumn.setSortable(sortable); + return this; + } + + /** + * Sets a header text to both columns. + * + * @see Column#setHeader(String) + * + * @param labelText the text to be shown at the columns headers + * @return this instance, for method chaining + */ + public TwinColumn setHeader(String labelText) { + availableColumn.setHeader(labelText); + selectionColumn.setHeader(labelText); + return this; + } + + /** + * Sets a footer text to both columns. + * + * @see Column#setFooter(String) + * + * @param labelText the text to be shown at the columns footers + * @return this instance, for method chaining + */ + public TwinColumn setFooter(String labelText) { + availableColumn.setFooter(labelText); + selectionColumn.setFooter(labelText); + return this; + } + + /** + * Sets a header component to both columns. + * + * @see Column#setHeader(String) + * + * @param headerComponentSupplier a supplier that instantiates the component to be used in the + * header of each column + * @return this instance, for method chaining + */ + public TwinColumn setHeader(Supplier footerComponentSupplier) { + availableColumn.setHeader(footerComponentSupplier.get()); + selectionColumn.setHeader(footerComponentSupplier.get()); + return this; + } + + /** + * Sets a footer component to both columns. + * + * @see Column#setFooter(String) + * + * @param footerComponentSuppleir a supplier that instantiates the component to be used in the + * footer of each column + * @return this instance, for method chaining + */ + public TwinColumn setFooter(Supplier footerComponentSupplier) { + availableColumn.setFooter(footerComponentSupplier.get()); + selectionColumn.setFooter(footerComponentSupplier.get()); + return this; + } + + /** + * Sets the function that is used for generating CSS class names for cells in both columns. + * + * @see Column#setClassNameGenerator(SerializableFunction) + * + * @param classNameGenerator the class name generator to set, not {@code null} + * @return this instance, for method chaining + * @throws NullPointerException if {@code classNameGenerator} is {@code null} + */ + public TwinColumn setClassNameGenerator(SerializableFunction classNameGenerator) { + availableColumn.setClassNameGenerator(classNameGenerator); + selectionColumn.setClassNameGenerator(classNameGenerator); + return this; + } + +} From 82b1b5777182faf1ec5a94bb2e531bf8c99b9a1f Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 26 Dec 2022 15:29:50 -0300 Subject: [PATCH 06/12] refactor!: move addColumn(ItemLabelGenerator, String) to legacy class --- .../addons/twincolgrid/LegacyTwinColGrid.java | 20 +++++++++++++++++++ .../addons/twincolgrid/TwinColGrid.java | 15 -------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java index 22ae1f6..1a06613 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java @@ -1,7 +1,9 @@ package com.flowingcode.vaadin.addons.twincolgrid; +import com.vaadin.flow.component.ItemLabelGenerator; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.data.provider.ListDataProvider; +import com.vaadin.flow.data.renderer.TextRenderer; import com.vaadin.flow.data.selection.SelectionListener; import java.util.Collection; import java.util.function.Supplier; @@ -280,4 +282,22 @@ protected void setDataProvider(ListDataProvider dataProvider) { super.setDataProvider(dataProvider); } + /** + * Adds a new text column to this {@link Grid} with a value provider. The column will use a + * {@link TextRenderer}. The value is converted to a String using the provided {@code + * itemLabelGenerator}. + * + * @deprecated Use {@link #addColumn(ItemLabelGenerator)}{@code .setHeader(header)} + * + * @param itemLabelGenerator the value provider + * @param header the column header + * @return this instance + */ + @Deprecated + public LegacyTwinColGrid addColumn( + final ItemLabelGenerator itemLabelGenerator, final String header) { + addColumn(itemLabelGenerator).setHeader(header); + return this; + } + } diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index 72574b5..a998efe 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -470,21 +470,6 @@ public TwinColumn addColumn(ItemLabelGenerator itemLabelGenerator) { return new TwinColumn<>(availableColumn, selectionColumn); } - /** - * Adds a new text column to this {@link Grid} with a value provider. The column will use a {@link - * TextRenderer}. The value is converted to a String using the provided {@code - * itemLabelGenerator}. - * - * @param itemLabelGenerator the value provider - * @param header the column header - * @return this instance - */ - public TwinColGrid addColumn( - final ItemLabelGenerator itemLabelGenerator, final String header) { - getAvailableGrid().addColumn(new TextRenderer<>(itemLabelGenerator)).setHeader(header); - getSelectionGrid().addColumn(new TextRenderer<>(itemLabelGenerator)).setHeader(header); - return this; - } /** * Adds a new sortable text column to this {@link Grid} with a value provider. The column will use From d6b210e7a2a4b2fc0169a6897b78c1e80c47aacd Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 26 Dec 2022 15:34:01 -0300 Subject: [PATCH 07/12] refactor!: move addSortableColumn to legacy class --- .../addons/twincolgrid/LegacyTwinColGrid.java | 53 +++++++++++++++++++ .../addons/twincolgrid/TwinColGrid.java | 51 ------------------ .../vaadin/addons/twincolgrid/BoundDemo.java | 5 +- .../addons/twincolgrid/DoubleClickDemo.java | 6 +-- .../addons/twincolgrid/DragAndDropDemo.java | 6 +-- .../addons/twincolgrid/OrientationDemo.java | 6 +-- 6 files changed, 64 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java index 1a06613..a913162 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java @@ -6,6 +6,7 @@ import com.vaadin.flow.data.renderer.TextRenderer; import com.vaadin.flow.data.selection.SelectionListener; import java.util.Collection; +import java.util.Comparator; import java.util.function.Supplier; import lombok.NonNull; @@ -300,4 +301,56 @@ public LegacyTwinColGrid addColumn( return this; } + /** + * Adds a new sortable text column to this {@link Grid} with a value provider. The column will use + * a {@link TextRenderer}. The value is converted to a String using the provided {@code + * itemLabelGenerator}. + * + * @deprecated Use + * {@link #addColumn(ItemLabelGenerator)}{@code .setHeader(header).setComparator(comparator)} + * + * @param itemLabelGenerator the value provider + * @param comparator the in-memory comparator + * @param header the column header + * @return this instance + */ + @Deprecated + public LegacyTwinColGrid addSortableColumn( + final ItemLabelGenerator itemLabelGenerator, + Comparator comparator, + final String header) { + addColumn(itemLabelGenerator) + .setHeader(header) + .setComparator(comparator) + .setSortable(true); + return this; + } + + /** + * Adds a new sortable text column to this {@link Grid} with a value provider. The column will use + * a {@link TextRenderer}. The value is converted to a String using the provided {@code + * itemLabelGenerator}. + * + * @deprecated Use + * {@link #addColumn(ItemLabelGenerator)}{@code .setHeader(header).setComparator(comparator).setKey(key)} + * + * @param itemLabelGenerator the value provider + * @param comparator the in-memory comparator + * @param header the column header + * @param header the column key + * @return this instance + */ + @Deprecated + public LegacyTwinColGrid addSortableColumn( + final ItemLabelGenerator itemLabelGenerator, + Comparator comparator, + final String header, + final String key) { + addColumn(itemLabelGenerator) + .setHeader(header) + .setComparator(comparator) + .setSortable(true) + .setKey(key); + return this; + } } diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index a998efe..d8695c5 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -55,7 +55,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -470,56 +469,6 @@ public TwinColumn addColumn(ItemLabelGenerator itemLabelGenerator) { return new TwinColumn<>(availableColumn, selectionColumn); } - - /** - * Adds a new sortable text column to this {@link Grid} with a value provider. The column will use - * a {@link TextRenderer}. The value is converted to a String using the provided {@code - * itemLabelGenerator}. - * - * @param itemLabelGenerator the value provider - * @param comparator the in-memory comparator - * @param header the column header - * @return this instance - */ - public TwinColGrid addSortableColumn( - final ItemLabelGenerator itemLabelGenerator, - Comparator comparator, - final String header) { - forEachGrid( - grid -> - grid.addColumn(new TextRenderer<>(itemLabelGenerator)) - .setHeader(header) - .setComparator(comparator) - .setSortable(true)); - return this; - } - - /** - * Adds a new sortable text column to this {@link Grid} with a value provider. The column will use - * a {@link TextRenderer}. The value is converted to a String using the provided {@code - * itemLabelGenerator}. - * - * @param itemLabelGenerator the value provider - * @param comparator the in-memory comparator - * @param header the column header - * @param header the column key - * @return this instance - */ - public TwinColGrid addSortableColumn( - final ItemLabelGenerator itemLabelGenerator, - Comparator comparator, - final String header, - final String key) { - forEachGrid( - grid -> - grid.addColumn(new TextRenderer<>(itemLabelGenerator)) - .setHeader(header) - .setComparator(comparator) - .setSortable(true) - .setKey(key)); - return this; - } - public TwinColGrid withoutAddAllButton() { addAllButton.setVisible(false); checkContainerVisibility(); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java index 48613fe..56c99d1 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/BoundDemo.java @@ -29,7 +29,6 @@ import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; @SuppressWarnings("serial") @@ -48,14 +47,14 @@ public BoundDemo() { // Binded final TwinColGrid twinColGrid = new TwinColGrid<>(availableBooks) - .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") - .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") .withSelectionGridCaption("Added books") .withoutRemoveAllButton() .withSizeFull() .selectRowOnClick(); + twinColGrid.addColumn(Book::getIsbn).setComparator(Book::getIsbn).setHeader("ISBN"); + twinColGrid.addColumn(Book::getTitle).setComparator(Book::getTitle).setHeader("Title"); twinColGrid.setCaption("TwinColGrid demo with Binder and row select without checkbox"); final Binder binder = new Binder<>(); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java index d693885..4e2aeeb 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java @@ -25,7 +25,6 @@ import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -44,12 +43,13 @@ public DoubleClickDemo() { final TwinColGrid twinColGrid = new TwinColGrid<>(availableBooks) - .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") - .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") .withSelectionGridCaption("Added books") .withSizeFull() .selectRowOnClick(); + + twinColGrid.addColumn(Book::getIsbn).setComparator(Book::getIsbn).setHeader("ISBN"); + twinColGrid.addColumn(Book::getTitle).setComparator(Book::getTitle).setHeader("Title"); twinColGrid.setValue(selectedBooks); add(new Span("Move items by double click"), twinColGrid); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java index 6028d29..9658eff 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DragAndDropDemo.java @@ -30,7 +30,6 @@ import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -51,8 +50,6 @@ public DragAndDropDemo() { twinColGrid = new TwinColGrid<>(availableBooks) - .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") - .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") .withSelectionGridCaption("Added books") .withoutAddAllButton() @@ -61,6 +58,9 @@ public DragAndDropDemo() { .withSelectionGridReordering() .selectRowOnClick(); + twinColGrid.addColumn(Book::getIsbn).setComparator(Book::getIsbn).setHeader("ISBN"); + twinColGrid.addColumn(Book::getTitle).setComparator(Book::getTitle).setHeader("Title"); + twinColGrid.setCaption("TwinColGrid demo with drag and drop support"); twinColGrid.setValue(selectedBooks); diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java index 625efa6..ac54453 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java @@ -27,7 +27,6 @@ import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -46,13 +45,14 @@ public OrientationDemo() { final TwinColGrid twinColGrid = new TwinColGrid<>(availableBooks) - .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN") - .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title") .withAvailableGridCaption("Available books") .withSelectionGridCaption("Added books") .withSizeFull() .selectRowOnClick() .withOrientation(Orientation.VERTICAL); + + twinColGrid.addColumn(Book::getIsbn).setComparator(Book::getIsbn).setHeader("ISBN"); + twinColGrid.addColumn(Book::getTitle).setComparator(Book::getTitle).setHeader("Title"); twinColGrid.setValue(selectedBooks); FormLayout formLayout = new FormLayout(); From 950ebddacf9ae3bffe72768b445753f72b1abf03 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:23:45 -0300 Subject: [PATCH 08/12] refactor!: refactor addFilterableColumn --- .../twincolgrid/FilterableTwinColumn.java | 127 ++++++++++++++++++ .../addons/twincolgrid/LegacyTwinColGrid.java | 68 ++++++++++ .../addons/twincolgrid/TwinColGrid.java | 90 +++++-------- .../addons/twincolgrid/FilterableDemo.java | 8 +- 4 files changed, 236 insertions(+), 57 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableTwinColumn.java diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableTwinColumn.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableTwinColumn.java new file mode 100644 index 0000000..0e002cf --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableTwinColumn.java @@ -0,0 +1,127 @@ +package com.flowingcode.vaadin.addons.twincolgrid; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.grid.Grid.Column; +import com.vaadin.flow.component.grid.SortOrderProvider; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.function.SerializableFunction; +import com.vaadin.flow.function.ValueProvider; +import java.util.Comparator; +import java.util.function.Supplier; + +/** Fluent helper object that delegates setters on both columns. */ +public class FilterableTwinColumn extends TwinColumn { + + public FilterableTwinColumn(Column availableColumn, Column selectionColumn) { + super(availableColumn, selectionColumn); + } + + /** + * Set the placeholder of the filter text field on both columns. + * + * @see TextField#setPlaceholder(String) + */ + public FilterableTwinColumn setFilterPlaceholder(String filterPlaceholder) { + TwinColGrid.getFilterTextField(getAvailableColumn()).setPlaceholder(filterPlaceholder); + TwinColGrid.getFilterTextField(getSelectionColumn()).setPlaceholder(filterPlaceholder); + return this; + } + + /** + * Set to {@code false} to hide the clear button which clears the filter text field. + * + * @see TextField#setClearButtonVisible(boolean) + */ + public FilterableTwinColumn setClearButtonVisible(boolean clearButtonVisible) { + TwinColGrid.getFilterTextField(getAvailableColumn()).setClearButtonVisible(clearButtonVisible); + TwinColGrid.getFilterTextField(getSelectionColumn()).setClearButtonVisible(clearButtonVisible); + return this; + } + + @Override + public FilterableTwinColumn setWidth(String width) { + super.setWidth(width); + return this; + } + + @Override + public FilterableTwinColumn setFlexGrow(int flexGrow) { + super.setFlexGrow(flexGrow); + return this; + } + + @Override + public FilterableTwinColumn setAutoWidth(boolean autoWidth) { + super.setAutoWidth(autoWidth); + return this; + } + + @Override + public FilterableTwinColumn setKey(String key) { + super.setKey(key); + return this; + } + + @Override + public FilterableTwinColumn setComparator(Comparator comparator) { + super.setComparator(comparator); + return this; + } + + @Override + public > TwinColumn setComparator( + ValueProvider keyExtractor) { + super.setComparator(keyExtractor); + return this; + } + + @Override + public FilterableTwinColumn setSortProperty(String... properties) { + super.setSortProperty(properties); + return this; + } + + @Override + public FilterableTwinColumn setSortOrderProvider(SortOrderProvider provider) { + super.setSortOrderProvider(provider); + return this; + } + + @Override + public FilterableTwinColumn setSortable(boolean sortable) { + super.setSortable(sortable); + return this; + } + + @Override + public FilterableTwinColumn setHeader(String labelText) { + super.setHeader(labelText); + return this; + } + + @Override + public FilterableTwinColumn setFooter(String labelText) { + super.setFooter(labelText); + return this; + } + + @Override + public FilterableTwinColumn setHeader(Supplier footerComponentSupplier) { + super.setHeader(footerComponentSupplier); + return this; + } + + @Override + public FilterableTwinColumn setFooter(Supplier footerComponentSupplier) { + super.setFooter(footerComponentSupplier); + return this; + } + + @Override + public FilterableTwinColumn setClassNameGenerator( + SerializableFunction classNameGenerator) { + super.setClassNameGenerator(classNameGenerator); + return this; + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java index a913162..31c5d4d 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/LegacyTwinColGrid.java @@ -5,6 +5,7 @@ import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.data.renderer.TextRenderer; import com.vaadin.flow.data.selection.SelectionListener; +import com.vaadin.flow.function.SerializableFunction; import java.util.Collection; import java.util.Comparator; import java.util.function.Supplier; @@ -353,4 +354,71 @@ public LegacyTwinColGrid addSortableColumn( .setKey(key); return this; } + + /** + * Adds a new filterable text column to this {@link TwinColGrid}, with a key. The value is + * converted to a String using the provided {@code itemLabelGenerator} and matches are computed + * against the result of {@code filterableValue}. + * + * @deprecated Use {@code addFilterableColumn(itemLabelGenerator, filterableValue)} and configure + * the other properties on the returned {@link TwinColumn}. + */ + @Deprecated + public LegacyTwinColGrid addFilterableColumn(final ItemLabelGenerator itemLabelGenerator, + SerializableFunction filterableValue, final String header, + String filterPlaceholder, boolean enableClearButton, String key) { + TwinColumn column = + addFilterableColumn(itemLabelGenerator, filterableValue).setHeader(header) + .setFilterPlaceholder(filterPlaceholder).setClearButtonVisible(enableClearButton); + if (key != null) { + column.setKey(key); + } + return this; + } + + /** + * Adds a new filterable text column to this {@link TwinColGrid}, with no key. The value is + * converted to a String using the provided {@code itemLabelGenerator} and matches are computed + * against the result of the same {@code itemLabelGenerator}. + * + * @deprecated Use {@code addFilterableColumn(itemLabelGenerator)} and configure the other + * properties on the returned {@link TwinColumn}. + */ + @Deprecated + public LegacyTwinColGrid addFilterableColumn(final ItemLabelGenerator itemLabelGenerator, + final String header, String filterPlaceholder, boolean enableClearButton) { + return addFilterableColumn(itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, + enableClearButton, null); + } + + /** + * Adds a new filterable text column to this {@link TwinColGrid}, with no key. The value is + * converted to a String using the provided {@code itemLabelGenerator} and matches are computed + * against the result of {@code filterableValue}. + * + * @deprecated Use {@code addFilterableColumn(itemLabelGenerator, filterableValue)} and configure + * the other properties on the returned {@link TwinColumn}. + */ + @Deprecated + public LegacyTwinColGrid addFilterableColumn(ItemLabelGenerator itemLabelGenerator, + SerializableFunction filterableValue, String header, String filterPlaceholder, + boolean enableClearButton) { + return addFilterableColumn(itemLabelGenerator, filterableValue, header, filterPlaceholder, + enableClearButton, null); + } + + /** + * Adds a new filterable text column to this {@link TwinColGrid}, with a key. The value is + * converted to a String using the provided {@code itemLabelGenerator} and matches are computed + * against the result of the same {@code itemLabelGenerator}. + * + * @deprecated Use {@code addFilterableColumn(itemLabelGenerator)} and configure the other + * properties on the returned {@link TwinColumn}. + */ + @Deprecated + public LegacyTwinColGrid addFilterableColumn(ItemLabelGenerator itemLabelGenerator, + String header, String filterPlaceholder, boolean enableClearButton, String key) { + return addFilterableColumn(itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, + enableClearButton, key); + } } diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index d8695c5..2a511b1 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -23,6 +23,7 @@ import com.vaadin.flow.component.AbstractField.ComponentValueChangeEvent; import com.vaadin.flow.component.ClientCallable; import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.ComponentUtil; import com.vaadin.flow.component.HasComponents; import com.vaadin.flow.component.HasSize; import com.vaadin.flow.component.HasValue; @@ -759,71 +760,50 @@ public boolean isSelectionGridReorderingAllowed() { return selection.allowReordering; } - public TwinColGrid addFilterableColumn( - final ItemLabelGenerator itemLabelGenerator, - SerializableFunction filterableValue, - final String header, - String filterPlaceholder, - boolean enableClearButton, - String key) { - forEachSide( - side -> { - Column column = - side.grid.addColumn(new TextRenderer<>(itemLabelGenerator)).setHeader(header); + private static final String COMPONENT_DATA_FILTER = "TwinColGrid#filterTF"; - Optional.ofNullable(key).ifPresent(column::setKey); - - TextField filterTF = new TextField(); - filterTF.setClearButtonVisible(enableClearButton); + private Column createFilterableColumn(TwinColModel side, + ItemLabelGenerator itemLabelGenerator, + SerializableFunction filterableValue) { + Column column = side.grid.addColumn(new TextRenderer<>(itemLabelGenerator)); + TextField filterTF = new TextField(); + + filterTF.addValueChangeListener( + event -> + side.getDataProvider() + .addFilter( + filterableEntity -> + StringUtils.containsIgnoreCase( + filterableValue.apply(filterableEntity), filterTF.getValue()))); + + if (side.headerRow == null) { + side.headerRow = side.grid.appendHeaderRow(); + } - filterTF.addValueChangeListener( - event -> - side.getDataProvider() - .addFilter( - filterableEntity -> - StringUtils.containsIgnoreCase( - filterableValue.apply(filterableEntity), filterTF.getValue()))); + side.headerRow.getCell(column).setComponent(filterTF); - if (side.headerRow == null) { - side.headerRow = side.grid.appendHeaderRow(); - } + filterTF.setValueChangeMode(ValueChangeMode.EAGER); + filterTF.setSizeFull(); - side.headerRow.getCell(column).setComponent(filterTF); - filterTF.setValueChangeMode(ValueChangeMode.EAGER); - filterTF.setSizeFull(); - filterTF.setPlaceholder(filterPlaceholder); - }); - - return this; + ComponentUtil.setData(column, COMPONENT_DATA_FILTER, filterTF); + return column; } - public TwinColGrid addFilterableColumn( - final ItemLabelGenerator itemLabelGenerator, - final String header, - String filterPlaceholder, - boolean enableClearButton) { - return addFilterableColumn( - itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, enableClearButton, null); + static TextField getFilterTextField(Column column) { + return (TextField) ComponentUtil.getData(column, COMPONENT_DATA_FILTER); } - public TwinColGrid addFilterableColumn( - ItemLabelGenerator itemLabelGenerator, - SerializableFunction filterableValue, - String header, - String filterPlaceholder, - boolean enableClearButton) { - return addFilterableColumn( - itemLabelGenerator, filterableValue, header, filterPlaceholder, enableClearButton, null); + public FilterableTwinColumn addFilterableColumn(ItemLabelGenerator itemLabelGenerator) { + return addFilterableColumn(itemLabelGenerator, itemLabelGenerator); } - public TwinColGrid addFilterableColumn( - ItemLabelGenerator itemLabelGenerator, - String header, - String filterPlaceholder, - boolean enableClearButton, - String key) { - return addFilterableColumn( - itemLabelGenerator, itemLabelGenerator, header, filterPlaceholder, enableClearButton, key); + public FilterableTwinColumn addFilterableColumn(ItemLabelGenerator itemLabelGenerator, + SerializableFunction filterableValue) { + + Column availableColumn = createFilterableColumn(available, itemLabelGenerator, filterableValue); + Column selectionColumn = createFilterableColumn(selection, itemLabelGenerator, filterableValue); + + return new FilterableTwinColumn<>(availableColumn, selectionColumn); } public TwinColGrid selectRowOnClick() { diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java index 60cf525..9e4bb61 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/FilterableDemo.java @@ -43,12 +43,16 @@ public FilterableDemo() { final TwinColGrid twinColGrid = new TwinColGrid<>(availableBooks) - .addFilterableColumn(Book::getIsbn, Book::getIsbn, "ISBN", "ISBN Filter", true) - .addFilterableColumn(Book::getTitle, "Title", "Title filter", false) .withAvailableGridCaption("Available books") .withSelectionGridCaption("Added books") .withoutAddAllButton() .withSizeFull(); + + twinColGrid.addFilterableColumn(Book::getIsbn).setHeader("ISBN") + .setFilterPlaceholder("ISBN Filter").setClearButtonVisible(true); + twinColGrid.addFilterableColumn(Book::getTitle).setHeader("Title") + .setFilterPlaceholder("Title filter").setClearButtonVisible(false); + twinColGrid.setCaption("TwinColGrid demo with filtering support"); twinColGrid.setValue(selectedBooks); From cbd3ed8015d7cb84eb609d95b278695909538c55 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:52:26 -0300 Subject: [PATCH 09/12] build: upgrade Vaadin to 14.8.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e783473..8b99a23 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 2.9.3-SNAPSHOT TwinColGrid add-on - 14.8.1 + 14.8.20 1.8 1.8 UTF-8 From 2bdf6de95facb6607378cb3518a75d1319e43c14 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 27 Dec 2022 11:50:21 -0300 Subject: [PATCH 10/12] style: declare and assign listEvent value in the same line --- .../vaadin/addons/twincolgrid/TwinColGridListAdapter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java index 068e60e..fd93c7f 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGridListAdapter.java @@ -98,8 +98,8 @@ public Registration addValueChangeListener( delegate.addValueChangeListener( ev -> { List value = new ArrayList<>(ev.getValue()); - ValueChangeEvent> listEvent; - listEvent = new ValueChangeEventImpl(ev.isFromClient(), new ArrayList<>(value)); + ValueChangeEvent> listEvent = + new ValueChangeEventImpl(ev.isFromClient(), new ArrayList<>(value)); listener.valueChanged(listEvent); })); @@ -110,8 +110,8 @@ public Registration addValueChangeListener( .addSortListener( ev -> { List value = getValue(); - ValueChangeEvent> listEvent; - listEvent = new ValueChangeEventImpl(ev.isFromClient(), value); + ValueChangeEvent> listEvent = + new ValueChangeEventImpl(ev.isFromClient(), value); listener.valueChanged(listEvent); })); From a0e55d5b0c7d1c449e429791a845b516f70d3424 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Tue, 27 Dec 2022 14:31:00 -0300 Subject: [PATCH 11/12] fix: fix filterable column display Close #123 --- .../addons/twincolgrid/TwinColGrid.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java index 2a511b1..dcf65ca 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java +++ b/src/main/java/com/flowingcode/vaadin/addons/twincolgrid/TwinColGrid.java @@ -145,6 +145,8 @@ public enum Orientation { private boolean isFromClient = false; + private boolean explicitHeaderRow = true; + private static ListDataProvider emptyDataProvider() { return DataProvider.ofCollection(new LinkedHashSet<>()); } @@ -455,6 +457,39 @@ public TwinColGrid withSelectionGridCaption(final String caption) { return this; } + /** + * Configure this component to create the first header row (for column header labels). If no + * column will have a header, this property must be set to {@code false}. + * + *

+ * When this property is {@code true} (default), the first column added through this component + * will {@linkplain Grid#appendHeaderRow() append} a header row, which will be the "default header + * row" (used by {@code Column.setHeader}). If no headers are set, then the default header row + * will be empty. + * + *

+ * When this property is {@code false}, then {@code Column.setHeader} will allocate a header row + * when called (which prevents an empty row if no headers are set, but also replaces the filter + * componentes). + * + * @param value whether the first header row will be created when a column is added. + * @return this instance + */ + public TwinColGrid createFirstHeaderRow(boolean value) { + explicitHeaderRow = value; + return this; + } + + private void createFirstHeaderRowIfNeeded() { + if (explicitHeaderRow) { + forEachGrid(grid -> { + if (grid.getColumns().isEmpty() && grid.getHeaderRows().isEmpty()) { + grid.appendHeaderRow(); + } + }); + } + } + /** * Adds a column to each grids. Both columns will use a {@link TextRenderer} and the value * will be converted to a String by using the provided {@code itemLabelGenerator}. @@ -463,6 +498,7 @@ public TwinColGrid withSelectionGridCaption(final String caption) { * @return the pair of columns */ public TwinColumn addColumn(ItemLabelGenerator itemLabelGenerator) { + createFirstHeaderRowIfNeeded(); Column availableColumn = getAvailableGrid().addColumn(new TextRenderer<>(itemLabelGenerator)); Column selectionColumn = @@ -800,6 +836,8 @@ public FilterableTwinColumn addFilterableColumn(ItemLabelGenerator itemLab public FilterableTwinColumn addFilterableColumn(ItemLabelGenerator itemLabelGenerator, SerializableFunction filterableValue) { + createFirstHeaderRowIfNeeded(); + Column availableColumn = createFilterableColumn(available, itemLabelGenerator, filterableValue); Column selectionColumn = createFilterableColumn(selection, itemLabelGenerator, filterableValue); From 95499801bf83392e3a5abc99cff0fc19383babb2 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Thu, 9 Feb 2023 15:10:21 -0300 Subject: [PATCH 12/12] fix(demo): avoid use of deprecated constructor Close #133 --- .../flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java index ac54453..97accdc 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/OrientationDemo.java @@ -56,7 +56,8 @@ public OrientationDemo() { twinColGrid.setValue(selectedBooks); FormLayout formLayout = new FormLayout(); - Select orientationField = new Select<>(Orientation.values()); + Select orientationField = new Select<>(); + orientationField.setItems(Orientation.values()); orientationField.addValueChangeListener(ev -> twinColGrid.withOrientation(ev.getValue())); orientationField.setValue(twinColGrid.getOrientation()); orientationField.setWidth("225px");