withRightColumnCaption(final String caption) {
- return withSelectionGridCaption(caption);
- }
-
- /**
- * Sets the text shown above the grid with the available items. {@code null} clears the caption.
+ *
+ * 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.
*
- * @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
- * itemLabelGenerator}.
+ *
+ * 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 itemLabelGenerator the value provider
- * @param header the column header
+ * @param value whether the first header row will be created when a column is added.
* @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);
+ public TwinColGrid createFirstHeaderRow(boolean value) {
+ explicitHeaderRow = value;
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
- * @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;
+ private void createFirstHeaderRowIfNeeded() {
+ if (explicitHeaderRow) {
+ forEachGrid(grid -> {
+ if (grid.getColumns().isEmpty() && grid.getHeaderRows().isEmpty()) {
+ grid.appendHeaderRow();
+ }
+ });
+ }
}
/**
- * 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}.
+ * 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
- * @param comparator the in-memory comparator
- * @param header the column header
- * @param header the column key
- * @return this instance
+ * @return the pair of columns
*/
- 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 TwinColumn addColumn(ItemLabelGenerator itemLabelGenerator) {
+ createFirstHeaderRowIfNeeded();
+ Column availableColumn =
+ getAvailableGrid().addColumn(new TextRenderer<>(itemLabelGenerator));
+ Column selectionColumn =
+ getSelectionGrid().addColumn(new TextRenderer<>(itemLabelGenerator));
+ return new TwinColumn<>(availableColumn, selectionColumn);
}
public TwinColGrid withoutAddAllButton() {
@@ -742,28 +574,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
*
@@ -789,8 +599,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)));
}
/**
@@ -810,15 +620,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);
}
@@ -830,7 +642,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);
});
}
@@ -860,7 +673,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);
@@ -868,9 +682,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();
});
}
@@ -888,8 +703,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);
});
@@ -926,25 +741,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);
@@ -975,87 +796,65 @@ 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,
- 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);
+ private Column createFilterableColumn(TwinColModel side,
+ ItemLabelGenerator itemLabelGenerator,
+ SerializableFunction filterableValue) {
+ Column column = side.grid.addColumn(new TextRenderer<>(itemLabelGenerator));
+ TextField filterTF = new TextField();
- TextField filterTF = new TextField();
- filterTF.setClearButtonVisible(enableClearButton);
+ filterTF.addValueChangeListener(
+ event ->
+ side.getDataProvider()
+ .addFilter(
+ filterableEntity ->
+ StringUtils.containsIgnoreCase(
+ filterableValue.apply(filterableEntity), filterTF.getValue())));
- filterTF.addValueChangeListener(
- event ->
- side.getDataProvider()
- .addFilter(
- filterableEntity ->
- StringUtils.containsIgnoreCase(
- filterableValue.apply(filterableEntity), filterTF.getValue())));
+ if (side.headerRow == null) {
+ side.headerRow = side.grid.appendHeaderRow();
+ }
- if (side.headerRow == null) {
- side.headerRow = side.grid.appendHeaderRow();
- }
+ side.headerRow.getCell(column).setComponent(filterTF);
- side.headerRow.getCell(column).setComponent(filterTF);
- filterTF.setValueChangeMode(ValueChangeMode.EAGER);
- filterTF.setSizeFull();
- filterTF.setPlaceholder(filterPlaceholder);
- });
+ filterTF.setValueChangeMode(ValueChangeMode.EAGER);
+ filterTF.setSizeFull();
- 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) {
+
+ createFirstHeaderRowIfNeeded();
+
+ Column availableColumn = createFilterableColumn(available, itemLabelGenerator, filterableValue);
+ Column selectionColumn = createFilterableColumn(selection, itemLabelGenerator, filterableValue);
+
+ return new FilterableTwinColumn<>(availableColumn, selectionColumn);
}
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());
}
});
});
@@ -1077,9 +876,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;
}
@@ -1106,23 +903,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
@@ -1133,5 +933,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..fd93c7f 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, List> 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 =
+ 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 =
+ 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/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;
+ }
+
+}
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..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")
@@ -47,29 +46,38 @@ public BoundDemo() {
// Binded
final TwinColGrid twinColGrid =
- new TwinColGrid<>(
- availableBooks, "TwinColGrid demo with Binder and row select without checkbox")
- .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN")
- .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title")
+ new TwinColGrid<>(availableBooks)
.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<>();
binder.forField(twinColGrid.asList()).asRequired().bind(Library::getBooks, Library::setBooks);
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();
}
@@ -78,11 +86,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/DoubleClickDemo.java b/src/test/java/com/flowingcode/vaadin/addons/twincolgrid/DoubleClickDemo.java
index e6bc74f..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;
@@ -43,15 +42,15 @@ public DoubleClickDemo() {
initializeData();
final TwinColGrid twinColGrid =
- new TwinColGrid<>(availableBooks, null)
- .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN")
- .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title")
+ new TwinColGrid<>(availableBooks)
.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);
- twinColGrid.setMoveItemsByDoubleClick(true);
add(new Span("Move items by double click"), twinColGrid);
setSizeFull();
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..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;
@@ -49,9 +48,8 @@ public class DragAndDropDemo extends VerticalLayout {
public DragAndDropDemo() {
initializeData();
- twinColGrid = new TwinColGrid<>(availableBooks)
- .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN")
- .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title")
+ twinColGrid =
+ new TwinColGrid<>(availableBooks)
.withAvailableGridCaption("Available books")
.withSelectionGridCaption("Added books")
.withoutAddAllButton()
@@ -60,12 +58,19 @@ 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);
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 779dae3..9e4bb61 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,18 @@ public FilterableDemo() {
initializeData();
final TwinColGrid twinColGrid =
- new TwinColGrid<>(availableBooks, "TwinColGrid demo with filtering support")
- .addFilterableColumn(Book::getIsbn, Book::getIsbn, "ISBN", "ISBN Filter", true)
- .addFilterableColumn(Book::getTitle, "Title", "Title filter", false)
+ new TwinColGrid<>(availableBooks)
.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);
add(twinColGrid);
@@ -59,16 +64,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"));
}
-
}
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..97accdc 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;
@@ -45,18 +44,20 @@ public OrientationDemo() {
initializeData();
final TwinColGrid twinColGrid =
- new TwinColGrid<>(availableBooks, null)
- .addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN")
- .addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title")
+ new TwinColGrid<>(availableBooks)
.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();
- 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");