All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dominokit.domino.ui.datatable.ColumnConfig Maven / Gradle / Ivy

/*
 * Copyright © 2019 Dominokit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.dominokit.domino.ui.datatable;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.dominokit.domino.ui.datatable.ColumnUtils.fixElementWidth;
import static org.dominokit.domino.ui.utils.Domino.*;

import elemental2.dom.Element;
import elemental2.dom.HTMLTableCellElement;
import elemental2.dom.Node;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.dominokit.domino.ui.IsElement;
import org.dominokit.domino.ui.elements.TableRowElement;
import org.dominokit.domino.ui.icons.MdiIcon;
import org.dominokit.domino.ui.icons.lib.Icons;
import org.dominokit.domino.ui.menu.Menu;
import org.dominokit.domino.ui.menu.direction.BestSideUpDownDropDirection;
import org.dominokit.domino.ui.popover.Tooltip;
import org.dominokit.domino.ui.utils.ComponentMeta;
import org.dominokit.domino.ui.utils.DominoElement;
import org.dominokit.domino.ui.utils.ElementsFactory;
import org.dominokit.domino.ui.utils.ScreenMedia;

/**
 * Represents the configuration for a column within a data table.
 *
 * 

Usage example: * *

 * ColumnConfig nameColumn = ColumnConfig.create("name")
 *     .setTitle("User Name")
 *     .setWidth("200px")
 *     .sortable();
 * 
* * @param the type parameter indicating the data type the column is related to. */ public class ColumnConfig implements ElementsFactory, DataTableStyles { private final String name; private String filterKey; private String title; private ColumnHeader headElement; private String minWidth; private String maxWidth; private CellTextAlign cellTextAlign = CellTextAlign.LEFT; private CellTextAlign headerCellTextAlign = CellTextAlign.LEFT; private CellRenderer cellRenderer; private CellRenderer editableCellRenderer; private HeaderElementSupplier headerElementSupplier = columnTitle -> text(columnTitle); private CellStyler headerStyler = element -> {}; private CellStyler cellStyler = element -> {}; private boolean sortable = false; private String sortKey; private String width; private boolean fixed = false; private Node tooltipNode; private boolean showTooltip = true; private boolean hidden = false; private boolean pluginColumn; private ScreenMedia showOn; private ScreenMedia hideOn; private boolean drawTitle = true; private final List showHideListeners = new ArrayList<>(); private final List permanentHideListeners = new ArrayList<>(); private final List> subColumns = new ArrayList<>(); private ColumnConfig parent; private final Map columnMeta = new HashMap<>(); private final Menu menu; private MdiIcon menuIcon; /** * Factory method to create a new instance of {@link ColumnConfig} with the specified column name. * * @param name the name of the column * @param the data type * @return a new {@link ColumnConfig} instance */ public static ColumnConfig create(String name) { return new ColumnConfig<>(name); } /** * Factory method to create a new instance of {@link ColumnConfig} with the specified column name * and title. * * @param name the name of the column * @param title the title of the column * @param the data type * @return a new {@link ColumnConfig} instance */ public static ColumnConfig create(String name, String title) { return new ColumnConfig<>(name, title); } /** * Constructs a {@link ColumnConfig} with the specified name and title. * * @param name the name of the column * @param title the title of the column */ public ColumnConfig(String name, String title) { this.name = name; this.title = title; menuIcon = Icons.dots_vertical().addCss(dui_datatable_th_menu_icon); this.menu = Menu.create() .setTargetElement(menuIcon) .setDropDirection(new BestSideUpDownDropDirection()) .addOnAddItemHandler((menu1, menuItem) -> menuIcon.show()); menuIcon.hide(); } /** * Constructs a {@link ColumnConfig} with the specified name. * * @param name the name of the column */ public ColumnConfig(String name) { this(name, ""); } /** * Getter for the field title. * * @return a {@link java.lang.String} object */ public String getTitle() { return title; } /** * Returns the name of the column. * * @return the column name */ public String getName() { return name; } /** * Gets the filter key for the column. If a specific filter key is not set, it defaults to the * column name. * * @return the filter key or the column name if filter key is null */ public String getFilterKey() { return nonNull(filterKey) ? filterKey : getName(); } /** * Sets a specific key for filtering purposes on this column. * * @param filterKey the filter key to set * @return the current instance for chaining */ public ColumnConfig setFilterKey(String filterKey) { this.filterKey = filterKey; return this; } /** * Sets the minimum width constraint for this column. * * @param minWidth the minimum width to set * @return the current instance for chaining */ public ColumnConfig minWidth(String minWidth) { this.minWidth = minWidth; return this; } /** * Sets the maximum width constraint for this column. * * @param maxWidth the maximum width to set * @return the current instance for chaining */ public ColumnConfig maxWidth(String maxWidth) { this.maxWidth = maxWidth; return this; } /** * Gets the set width for this column. * * @return the width of the column */ public String getWidth() { return width; } /** * Sets the width for this column. * * @param width the desired width for the column * @return the current instance for chaining */ public ColumnConfig setWidth(String width) { this.width = width; return this; } /** * Sets the text alignment for cells within this column. * * @param cellTextAlign the alignment setting for the cell content * @return the current instance for chaining */ public ColumnConfig setTextAlign(CellTextAlign cellTextAlign) { this.cellTextAlign = cellTextAlign; return this; } /** * Sets the text alignment for the header cell of this column. * * @param headerCellTextAlign the alignment setting for the header cell content * @return the current instance for chaining */ public ColumnConfig setHeaderTextAlign(CellTextAlign headerCellTextAlign) { this.headerCellTextAlign = headerCellTextAlign; return this; } /** * Retrieves the header element supplier for this column. * * @return the header element supplier */ public HeaderElementSupplier getHeaderElementSupplier() { return headerElementSupplier; } /** * Sets the header element supplier for this column. * * @param headerElement the header element supplier to set * @return the current instance for chaining */ public ColumnConfig setHeaderElementSupplier(HeaderElementSupplier headerElement) { this.headerElementSupplier = headerElement; return this; } /** * Gets the minimum width of the column. * * @return the minimum width */ public String getMinWidth() { return minWidth; } /** * Gets the maximum width of the column. * * @return the maximum width */ public String getMaxWidth() { return maxWidth; } /** * Retrieves the text alignment for cells within this column. * * @return the cell text alignment */ public CellTextAlign getTextAlign() { return cellTextAlign; } /** * Retrieves the text alignment for the header cell of this column. * * @return the header cell text alignment */ public CellTextAlign getHeaderTextAlign() { return headerCellTextAlign; } /** * Checks if the column is fixed or not. * * @return true if the column is fixed, false otherwise */ public boolean isFixed() { return fixed; } /** * Sets the fixed status for this column. * * @param fixed the fixed status to set * @return the current instance for chaining */ public ColumnConfig setFixed(boolean fixed) { this.fixed = fixed; return this; } /** * Sets the title for this column. * * @param title the title to set * @return the current instance for chaining */ public ColumnConfig setTitle(String title) { this.title = title; return this; } /** * Retrieves the head element of this column. * * @return the head element */ public DominoElement getHeadElement() { return elementOf(headElement); } /** * Gets the renderer used for displaying cell data in this column. * * @return the cell renderer */ public CellRenderer getCellRenderer() { return cellRenderer; } /** * Sets the renderer for displaying cell data in this column. If the editable cell renderer is * null, it also updates the editable cell renderer. * * @param cellRenderer the cell renderer to set * @return the current instance for chaining */ public ColumnConfig setCellRenderer(CellRenderer cellRenderer) { this.cellRenderer = cellRenderer; if (isNull(editableCellRenderer)) { this.editableCellRenderer = cellRenderer; } return this; } /** * Gets the renderer used for editable cells in this column. If the editable cell renderer is * null, it returns the cell renderer. * * @return the editable cell renderer or the cell renderer if editable one is null */ public CellRenderer getEditableCellRenderer() { if (isNull(editableCellRenderer)) { return cellRenderer; } return editableCellRenderer; } /** * Sets the renderer for editable cells in this column. If the cell renderer is null, it also * updates the cell renderer. * * @param editableCellRenderer the editable cell renderer to set * @return the current instance for chaining */ public ColumnConfig setEditableCellRenderer(CellRenderer editableCellRenderer) { this.editableCellRenderer = editableCellRenderer; if (isNull(cellRenderer)) { this.cellRenderer = editableCellRenderer; } return this; } /** * Styles the header using the provided header styler. * * @param headerStyler the styler to be applied to the header * @return the current instance for chaining */ public ColumnConfig styleHeader(CellStyler headerStyler) { this.headerStyler = headerStyler; return this; } /** * Styles the cells using the provided cell styler. * * @param cellStyler the styler to be applied to the cells * @return the current instance for chaining */ public ColumnConfig styleCell(CellStyler cellStyler) { this.cellStyler = cellStyler; return this; } /** * Checks if the column is sortable. * * @return true if the column is sortable, false otherwise */ public boolean isSortable() { return sortable; } /** * Sets the sortable status of the column using the default sort key. * * @param sortable the sortable status to set * @return the current instance for chaining */ public ColumnConfig setSortable(boolean sortable) { return setSortable(sortable, name); } /** * Sets the sortable status of the column with a specified sort key. * * @param sortable the sortable status to set * @param sortKey the sort key to use * @return the current instance for chaining */ public ColumnConfig setSortable(boolean sortable, String sortKey) { this.sortable = sortable; this.sortKey = sortKey; return this; } /** * Sets the column as sortable using the default sort key. * * @return the current instance for chaining */ public ColumnConfig sortable() { return setSortable(true, name); } /** * Sets the column as sortable with a specified sort key. * * @param sortKey the sort key to use * @return the current instance for chaining */ public ColumnConfig sortable(String sortKey) { return setSortable(true, sortKey); } /** * Applies the screen media styles to the provided element. * * @param element the element to apply styles to */ public void applyScreenMedia(Element element) { DominoElement thElement = elements.elementOf(element); if (nonNull(showOn)) { thElement.showOn(showOn); } if (nonNull(hideOn)) { thElement.hideOn(hideOn); } } /** * Retrieves the tooltip node for this column. If it's not explicitly set, it uses the header * element supplier's element for the title. * * @return the tooltip node */ public Node getTooltipNode() { if (nonNull(tooltipNode)) return tooltipNode; else { return getHeaderElementSupplier().asElement(title); } } /** * Sets the tooltip node for this column. * * @param tooltipNode the tooltip node to set * @return the current instance for chaining */ public ColumnConfig setTooltipNode(Node tooltipNode) { this.tooltipNode = tooltipNode; return this; } /** * Sets the tooltip text for this column. This also sets the tooltip node. * * @param tooltipText the tooltip text to set * @return the current instance for chaining */ public ColumnConfig setTooltipText(String tooltipText) { this.tooltipNode = elements.text(tooltipText); return this; } /** * Sets the visibility of the tooltip for this column. * * @param showTooltip true to show the tooltip, false otherwise * @return the current instance for chaining */ public ColumnConfig setShowTooltip(boolean showTooltip) { this.showTooltip = showTooltip; return this; } /** * Retrieves the screen media on which the column is shown. * * @return the screen media for showing the column */ public ScreenMedia getShowOn() { return showOn; } /** * Sets the screen media on which the column should be shown. * * @param showOn the screen media for showing the column * @return the current instance for chaining */ public ColumnConfig showOn(ScreenMedia showOn) { this.showOn = showOn; return this; } /** * Retrieves the screen media on which the column is hidden. * * @return the screen media for hiding the column */ public ScreenMedia getHideOn() { return hideOn; } /** * Sets the screen media on which the column should be hidden. * * @param hideOn the screen media for hiding the column * @return the current instance for chaining */ public ColumnConfig hideOn(ScreenMedia hideOn) { this.hideOn = hideOn; return this; } /** Applies header styling to the header element. */ void applyHeaderStyle() { headerStyler.styleCell(headElement.element()); } /** * Applies cell styling to the given element. * * @param element the element to be styled */ void applyCellStyle(Element element) { cellStyler.styleCell(element); } /** * Retrieves the styler used for the header. * * @return the header styler */ public CellStyler getHeaderStyler() { return headerStyler; } /** * Retrieves the styler used for the cells. * * @return the cell styler */ public CellStyler getCellStyler() { return cellStyler; } /** * Checks if tooltips are shown for the column and the column has a tooltip node or has a title. * * @return true if tooltips are shown and there is a tooltip node or a title, false otherwise */ public boolean isShowTooltip() { return showTooltip && (nonNull(tooltipNode) || (nonNull(title) && !title.trim().isEmpty())); } /** * Adds a show/hide listener to the column. * * @param showHideListener the listener to be added * @return the current instance for chaining */ public ColumnConfig addShowHideListener(ColumnShowHideListener showHideListener) { if (showHideListener.isPermanent()) { this.permanentHideListeners.add(showHideListener); } else { this.showHideListeners.add(showHideListener); } return this; } /** * Removes a show/hide listener from the column. * * @param showHideListener the listener to be removed * @return the current instance for chaining */ public ColumnConfig removeShowHideListener(ColumnShowHideListener showHideListener) { if (showHideListener.isPermanent()) { this.permanentHideListeners.remove(showHideListener); } else { this.showHideListeners.remove(showHideListener); } return this; } /** * Makes the column visible. * * @return the current instance for chaining */ public ColumnConfig show() { this.permanentHideListeners.forEach(showHideListener -> showHideListener.onShowHide(true)); this.showHideListeners.forEach(showHideListener -> showHideListener.onShowHide(true)); this.hidden = false; return this; } /** * Hides the column. * * @return the current instance for chaining */ public ColumnConfig hide() { this.permanentHideListeners.forEach(showHideListener -> showHideListener.onShowHide(false)); this.showHideListeners.forEach(showHideListener -> showHideListener.onShowHide(false)); this.hidden = true; return this; } /** * Toggles the display of the column. * * @param visible true to make the column visible, false to hide * @return the current instance for chaining */ public ColumnConfig toggleDisplay(boolean visible) { if (visible) { return show(); } else { return hide(); } } /** @deprecated Use {@link #clearShowHideListeners()} instead. */ @Deprecated public void clearShowHideListners() { clearShowHideListeners(); } /** Clears all non-permanent show/hide listeners. */ public void clearShowHideListeners() { showHideListeners.clear(); } /** * Checks if the column is hidden. * * @return true if the column is hidden, false otherwise */ public boolean isHidden() { return hidden; } /** * Checks if the column is a plugin column. * * @return true if the column is a plugin column, false otherwise */ public boolean isPluginColumn() { return pluginColumn; } /** * Sets the column as a plugin column. * * @param pluginColumn true to mark the column as a plugin column * @return the current instance for chaining */ public ColumnConfig setPluginColumn(boolean pluginColumn) { this.pluginColumn = pluginColumn; return this; } /** * Retrieves the sort key of the column, defaulting to the column name if not set. * * @return the sort key of the column */ public String getSortKey() { return Optional.ofNullable(sortKey).orElse(name); } /** * Checks if the column is a utility column. * * @return true if the column is a utility column, false otherwise */ public final boolean isUtilityColumn() { return "plugin-utility-column".equals(name); } /** * Checks if the column title is drawn. * * @return true if the title is drawn, false otherwise */ public boolean isDrawTitle() { return drawTitle; } /** * Sets whether the column title should be drawn. * * @param drawTitle true to draw the title, false otherwise * @return the current instance for chaining */ public ColumnConfig setDrawTitle(boolean drawTitle) { this.drawTitle = drawTitle; return this; } /** * Adds a sub-column to the current column. * * @param column the sub-column to be added * @return the current instance for chaining */ public ColumnConfig addColumn(ColumnConfig column) { column.parent = this; column.applyMeta(ColumnHeaderMeta.create()); this.subColumns.add(column); return this; } /** * Checks if the column is a group of sub-columns. * * @return true if the column has sub-columns, false otherwise */ public boolean isColumnGroup() { return !this.subColumns.isEmpty(); } /** * Retrieves the total number of columns under this column, including itself. * * @return the total count of columns */ public int getColumnsCount() { if (!isColumnGroup()) { return 1; } return this.subColumns.stream().map(ColumnConfig::getColumnsCount).reduce(0, Integer::sum); } /** * Retrieves the depth of the column in terms of nested sub-columns. * * @return the depth of the column */ public int getColumnsDepth() { if (!isColumnGroup()) { return getGroupLevel(); } return this.subColumns.stream().mapToInt(ColumnConfig::getColumnsDepth).max().orElse(0); } /** * Retrieves the level of the column in terms of nesting. * * @return the level of the column */ public int getGroupLevel() { if (isNull(parent)) { return 0; } return 1 + parent.getGroupLevel(); } /** * Retrieves the colspan value for the column. * * @return the colspan value */ private int getColSpan() { if (!isColumnGroup()) { return 1; } return subColumns.stream().mapToInt(ColumnConfig::getColSpan).sum(); } /** * Flattens the structure of the column, including all its sub-columns. * * @return a list of all columns under this column, including itself */ public List> flattenColumns() { List> cols = new ArrayList<>(); cols.add(this); if (isColumnGroup()) { subColumns.forEach(col -> cols.addAll(col.flattenColumns())); } return cols; } /** * Retrieves only the leaf columns under this column. * * @return a list of leaf columns */ public List> leafColumns() { List> cols = new ArrayList<>(); if (!isColumnGroup()) { cols.add(this); } else { subColumns.forEach(col -> cols.addAll(col.leafColumns())); } return cols; } /** * Retrieves the direct sub-columns of this column. * * @return a list of direct sub-columns */ public List> getSubColumns() { return subColumns; } /** * Checks if the column has a parent column. * * @return true if the column has a parent, false otherwise */ public boolean hasParent() { return nonNull(parent); } /** * Associates metadata with the column. * * @param meta the metadata to be associated with the column * @return the current instance for chaining */ public ColumnConfig applyMeta(ComponentMeta meta) { columnMeta.put(meta.getKey(), meta); return this; } /** * Retrieves the metadata associated with a given key. * * @param key the key for which metadata is to be retrieved * @return an optional containing the metadata if present, otherwise an empty optional */ @SuppressWarnings("all") public Optional getMeta(String key) { return Optional.ofNullable((C) columnMeta.get(key)); } /** * Removes the metadata associated with a given key. * * @param key the key for which metadata is to be removed * @return the current instance for chaining */ public ColumnConfig removeMeta(String key) { columnMeta.remove(key); return this; } /** * Renders the header of the column. * * @param dataTable the data table to which the column belongs * @param tableConfig the configuration of the table * @param headers the row elements that make up the headers */ void renderHeader(DataTable dataTable, TableConfig tableConfig, TableRowElement[] headers) { int depth = getColumnsDepth(); int startIndex = headers.length - 1 - depth; if (startIndex == 0) { elementOf(headers[0]).appendChild(createColumnElement(tableConfig)); } else { ColumnHeader fillHeader = createColumnElement(tableConfig) .clearElement() .apply(self -> self.setAttribute("rowspan", startIndex + "")); ColumnHeaderMeta.get(this) .ifPresent(columnHeaderMeta -> columnHeaderMeta.addExtraHeadElement(fillHeader)); elementOf(headers[0]).appendChild(fillHeader); elementOf(headers[startIndex]).appendChild(createColumnElement(tableConfig)); } if (isColumnGroup()) { renderChildColumns(dataTable, tableConfig, headers, startIndex + 1); } tableConfig.getPlugins().forEach(plugin -> plugin.onHeaderAdded(dataTable, this)); } /** * Renders the child columns under this column. * * @param dataTable the data table to which the column belongs * @param tableConfig the configuration of the table * @param headers the row elements that make up the headers * @param startIndex the starting index to begin rendering child columns */ private void renderChildColumns( DataTable dataTable, TableConfig tableConfig, TableRowElement[] headers, int startIndex) { getSubColumns() .forEach( col -> { if (col.isColumnGroup()) { elementOf(headers[startIndex]) .appendChild( col.createColumnElement(tableConfig) .apply( self -> { if (startIndex < (headers.length - col.getColumnsDepth())) { int diff = headers.length - col.getColumnsDepth() - 1; self.setAttribute("rowspan", diff + 1 + ""); } })); col.renderChildColumns(dataTable, tableConfig, headers, startIndex + 1); } else { int index = headers.length - 1; if (index > startIndex) { int diff = startIndex - index; ColumnHeader fillHeader = col.createColumnElement(tableConfig) .clearElement() .setAttribute("rowspan", diff + ""); ColumnCssRuleMeta.get(this) .ifPresent( meta -> meta.cssRules() .forEach( columnCssRule -> fillHeader.addCss( columnCssRule.getCssRule().getCssClass()))); ColumnHeaderMeta.get(col) .ifPresent( columnHeaderMeta -> columnHeaderMeta.addExtraHeadElement(fillHeader)); elementOf(headers[startIndex]).appendChild(fillHeader); } elementOf(headers[index]).appendChild(col.createColumnElement(tableConfig)); tableConfig.getPlugins().forEach(plugin -> plugin.onHeaderAdded(dataTable, col)); } }); } /** * Creates a column header element based on the table configuration and column properties. * * @param tableConfig the configuration of the table * @return the created column header */ private ColumnHeader createColumnElement(TableConfig tableConfig) { if (isDrawTitle() && nonNull(getTitle())) { this.headElement = ColumnHeader.create(getHeaderElementSupplier().asElement(getTitle())); } else { this.headElement = ColumnHeader.create(); } this.headElement.setAttribute("colspan", getColSpan() + "").appendChild(menuIcon); if (isColumnGroup()) { this.headElement.addCss("dui-column-group"); } if (nonNull(getHeaderTextAlign())) { this.headElement.addCss(getHeaderTextAlign()); } ColumnCssRuleMeta.get(this) .ifPresent( meta -> meta.cssRules() .forEach( columnCssRule -> this.headElement.addCss(columnCssRule.getCssRule().getCssClass()))); applyScreenMedia(this.headElement.element()); if (tableConfig.isFixed() || isFixed()) { fixElementWidth(this, this.headElement.element()); } if (isShowTooltip()) { Tooltip.create(this.headElement.element(), getTooltipNode()); } applyHeaderStyle(); addShowHideListener(DefaultColumnShowHideListener.of(this.headElement.element(), true)); this.headElement.toggleDisplay(!isHidden()); return this.headElement; } /** * Applies the given handler to this column and recursively to all of its sub-columns. * * @param handler the consumer to be applied * @return the current column instance for chaining */ public ColumnConfig applyAndOnSubColumns(Consumer> handler) { handler.accept(this); if (isColumnGroup()) { getSubColumns().forEach(col -> col.applyAndOnSubColumns(handler)); } return this; } /** * Applies the given handler to this column and recursively to all of its sub-columns if they * satisfy the given predicate. * * @param predicate the condition to be checked before applying the handler * @param handler the consumer to be applied if the predicate is true * @return the current column instance for chaining */ public ColumnConfig applyAndOnSubColumns( Predicate> predicate, Consumer> handler) { handler.accept(this); if (isColumnGroup()) { getSubColumns().forEach(col -> col.applyAndOnSubColumns(handler)); } return this; } /** * Applies the given handler to this column and recursively to the first sub-column of each * subsequent column group. * * @param handler the consumer to be applied * @return the current column instance for chaining */ public ColumnConfig applyAndOnEachFirstSubColumn(Consumer> handler) { handler.accept(this); if (isColumnGroup()) { getSubColumns().get(0).applyAndOnEachFirstSubColumn(handler); } return this; } /** * Applies the given handler to the first sub-column of this column. * * @param handler the consumer to be applied * @return the current column instance for chaining */ public ColumnConfig onFirstSubColumn(Consumer> handler) { if (isColumnGroup()) { getSubColumns().get(0).applyAndOnEachFirstSubColumn(handler); } return this; } /** * Applies the given handler to this column and recursively to the last sub-column of each * subsequent column group. * * @param handler the consumer to be applied * @return the current column instance for chaining */ public ColumnConfig applyAndOnEachLastSubColumn(Consumer> handler) { handler.accept(this); if (isColumnGroup()) { getSubColumns().get(getSubColumns().size() - 1).applyAndOnEachLastSubColumn(handler); } return this; } /** * Applies the given handler to the last sub-column of this column. * * @param handler the consumer to be applied * @return the current column instance for chaining */ public ColumnConfig onEachLastSubColumn(Consumer> handler) { if (isColumnGroup()) { getSubColumns().get(getSubColumns().size() - 1).applyAndOnEachLastSubColumn(handler); } return this; } /** * Applies the given handler to this column and recursively to all of its parent columns. * * @param handler the consumer to be applied * @return the current column instance for chaining */ public ColumnConfig applyAndOnParents(Consumer> handler) { handler.accept(this); if (this.hasParent()) { getParent().applyAndOnParents(handler); } return this; } /** * Retrieves the grandparent column of this column, or itself if it doesn't have a grandparent. * * @return the grandparent column or the current column */ public ColumnConfig getGrandParent() { if (hasParent()) { return getParent().getGrandParent(); } return this; } /** * Retrieves the last grand sibling column of this column group. If the column is not a column * group, it retrieves itself. * * @return the last grand sibling column or the current column */ public ColumnConfig getLastGrandSiblingColumn() { if (!isColumnGroup()) { return this; } return this.getSubColumns().get(this.getSubColumns().size() - 1).getLastGrandSiblingColumn(); } /** * Retrieves the first grand sibling column of this column group. If the column is not a column * group, it retrieves itself. * * @return the first grand sibling column or the current column */ public ColumnConfig getFirstGrandSiblingColumn() { if (!isColumnGroup()) { return this; } return this.getSubColumns().get(0).getFirstGrandSiblingColumn(); } /** * Retrieves the associated menu of the column. * * @return the menu associated with the column */ public Menu getMenu() { return menu; } /** * Retrieves the parent column of this column. * * @return the parent column or null if this column does not have a parent */ public ColumnConfig getParent() { return parent; } /** * Appends the given element as a child to the header element of this column. * * @param element the element to be appended * @return the current column instance for chaining */ public ColumnConfig appendChild(IsElement element) { headElement.appendChild(element); return this; } /** * Removes the specified child node from the header element of this column if it is a direct * child. * * @param child the child node to be removed * @return the current column instance for chaining */ public ColumnConfig removeChild(Node child) { if (headElement.contains(child)) { headElement.removeChild(child); } return this; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ColumnConfig that = (ColumnConfig) o; return Objects.equals(name, that.name); } @Override public int hashCode() { return Objects.hash(name); } /** * Removes the specified child element from the header element of this column. * * @param child the child element to be removed * @return the current column instance for chaining */ public ColumnConfig removeChild(IsElement child) { return removeChild(child.element()); } /** Functional interface for styling the cells of a column. */ @FunctionalInterface public interface CellStyler { /** * Applies styling to the given cell element. * * @param element the cell element to be styled */ void styleCell(Element element); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy