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

com.holonplatform.vaadin7.components.builders.ItemListingBuilder Maven / Gradle / Ivy

/*
 * Copyright 2016-2017 Axioma srl.
 * 
 * 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 com.holonplatform.vaadin7.components.builders;

import java.io.Serializable;
import java.util.Arrays;

import com.holonplatform.core.Path;
import com.holonplatform.core.i18n.Localizable;
import com.holonplatform.core.i18n.LocalizationContext;
import com.holonplatform.core.internal.utils.ObjectUtils;
import com.holonplatform.core.query.QuerySort;
import com.holonplatform.vaadin7.components.BeanListing;
import com.holonplatform.vaadin7.components.ItemListing;
import com.holonplatform.vaadin7.components.ItemListing.CellStyleGenerator;
import com.holonplatform.vaadin7.components.ItemListing.ColumnAlignment;
import com.holonplatform.vaadin7.components.ItemListing.ItemClickListener;
import com.holonplatform.vaadin7.components.ItemListing.ItemDescriptionGenerator;
import com.holonplatform.vaadin7.components.ItemListing.ItemDetailsGenerator;
import com.holonplatform.vaadin7.components.ItemListing.PropertyReorderListener;
import com.holonplatform.vaadin7.components.ItemListing.PropertyResizeListener;
import com.holonplatform.vaadin7.components.ItemListing.PropertyVisibilityListener;
import com.holonplatform.vaadin7.components.ItemListing.RowStyleGenerator;
import com.holonplatform.vaadin7.components.Selectable.SelectionListener;
import com.holonplatform.vaadin7.components.Selectable.SelectionMode;
import com.holonplatform.vaadin7.data.ItemDataSource.CommitHandler;
import com.holonplatform.vaadin7.data.ItemDataSource.PropertySortGenerator;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.event.Action;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.server.Resource;
import com.vaadin.ui.Component;
import com.vaadin.ui.Field;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.FooterRow;
import com.vaadin.ui.Grid.HeaderRow;
import com.vaadin.ui.Grid.StaticSection;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.FooterClickListener;
import com.vaadin.ui.Table.HeaderClickListener;
import com.vaadin.ui.Table.RowGenerator;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.renderers.Renderer;

/**
 * Base {@link ItemListing} builder.
 * 
 * @param  Item data type
 * @param  Component type
 * @param 

Item property type * @param Concrete builder type * @param Concrete backing component type * * @since 5.0.0 */ public interface ItemListingBuilder, B extends ItemListingBuilder, X extends Component> extends ItemDataSourceComponentBuilder, ComponentPostProcessorSupport { /** * Set whether given property is sortable. * @param property Property (not null) * @param sortable Whether given property id is sortable * @return this */ B sortable(P property, boolean sortable); /** * Set whether given property is read-only. * @param property Property (not null) * @param readOnly Whether given property id is read-only * @return this */ B readOnly(P property, boolean readOnly); /** * Set a default value to initialize the given property. * @param property Property (not null) * @param defaultValue Default value * @return this */ B defaultValue(P property, Object defaultValue); /** * Declares to use specified {@link Path} to generate query sorts for given property. * @param property Property for which to declare the sort path (not null) * @param sortPath Sort path to use (not null) * @return this */ B sortUsing(P property, Path sortPath); /** * Set a {@link PropertySortGenerator} to generate {@link QuerySort}s for given property * @param property Property to sort (not null) * @param generator PropertySortGenerator (not null) * @return this */ B sortGenerator(P property, PropertySortGenerator

generator); /** * Set the handler to use to persist item set modifications. * @param commitHandler Handler to set (not null) * @return this */ B commitHandler(CommitHandler commitHandler); /** * Hides the table/grid column headers * @return this */ B hideHeaders(); /** * Add a {@link RowStyleGenerator} to generate row style names. * @param rowStyleGenerator Row style generator * @return this */ B withRowStyle(RowStyleGenerator rowStyleGenerator); /** * Set the column header to show for given property. *

* By default, if the property is {@link Localizable}, the {@link Localizable#getMessage()} (and * {@link Localizable#getMessageCode()} if a {@link LocalizationContext} is available) is used as column header. *

* @param property Item property to set the header for (not null) * @param header Localizable column header (not null) * @return this */ B header(P property, Localizable header); /** * Set the column header to show for given property. * @param property Item property to set the header for (not null) * @param header Column header * @return this */ default B header(P property, String header) { return header(property, Localizable.builder().message(header).build()); } /** * Set the column header to show for given property. * @param property Item property to set the header for (not null) * @param defaultHeader Default column header * @param headerMessageCode Column header translation message code * @return this */ default B header(P property, String defaultHeader, String headerMessageCode) { return header(property, Localizable.builder().message(defaultHeader).messageCode(headerMessageCode).build()); } /** * Set the text alignment for the column which corresponds to given property. * @param property Item property to set the alignment for (not null) * @param alignment Alignment * @return this */ B alignment(P property, ColumnAlignment alignment); /** * Set the width in pixels for the column which corresponds to given property. * @param property Item property to set the width for (not null) * @param widthInPixels Width in pixel * @return this */ B width(P property, int widthInPixels); /** * Set whether the column which corresponds to given property is editable when listing is in edit mode * (true by default). * @param property Item property to set editable or not (not null) * @param editable true to set the column editable, false otherwise * @return this */ B editable(P property, boolean editable); /** * Set the editor {@link Field} to use for given property in edit mode to obtain the field to use as property * editor. * @param property Item property to set the editor for (not null) * @param editor Editor field to set (not null) * @return this */ B editor(P property, Field editor); /** * Sets whether the column which corresponds to given property can be hidden by the user. * @param property Item property to set hidable or not (not null) * @param hidable true if the column which corresponds to given property can be hidden by the user * @return this */ B hidable(P property, boolean hidable); /** * Sets whether this column which corresponds to given property is hidden. * @param property Item property to set hidden or not (not null) * @param hidden true if column is hidden * @return this */ B hidden(P property, boolean hidden); /** * Set the {@link CellStyleGenerator} to call for given property to generate column cell style. * @param property Item property to set the style generator for (not null) * @param cellStyleGenerator Cell style generator (not null) * @return this */ B style(P property, CellStyleGenerator cellStyleGenerator); /** * Set the column cell style name for given property * @param property Item property to set the style for (not null) * @param styleName The property column style name * @return this */ default B style(P property, String styleName) { return style(property, (p, item) -> styleName); } /** * Set whether the editor mode is buffered or not. Default is true. *

* When buffered, the listing component requires a specific action to commit item modifications to persistence * store, using {@link ItemListing#commit()}. A listing using a Grid as backing component provides Save and * Cancel editor buttonsto commit or discard item changes. * @param buffered Buffered mode to set * @return this */ B buffered(boolean buffered); /** * Set the listing selection mode. * @param selectionMode Selection mode to set (not null). Use {@link SelectionMode#NONE} to disable selection. * @return this */ B selectionMode(SelectionMode selectionMode); /** * Add a {@link SelectionListener} to listen to items selection changes. *

* {@link SelectionListener}s are triggred only when listing is selectable, i.e. (i.e. {@link SelectionMode} is not * {@link SelectionMode#NONE}). *

* @param selectionListener Selection listener to add (not null) * @return this */ B withSelectionListener(SelectionListener selectionListener); /** * Set whether the listing is editable. * @param editable true to set the listing editable, false otherwise * @return this */ B editable(boolean editable); /** * Adds a {@link ItemClickListener} that gets notified when an item is clicked by the user. * @param listener ItemClickListener to add (not null) * @return this */ B withItemClickListener(ItemClickListener listener); /** * Adds a {@link PropertyReorderListener} that gets notified when property columns order changes. * @param listener Listener to add (not null) * @return this */ B withPropertyReorderListener(PropertyReorderListener

listener); /** * Adds a {@link PropertyResizeListener} that gets notified when a property column is resized. * @param listener Listener to add (not null) * @return this */ B withPropertyResizeListener(PropertyResizeListener

listener); /** * Adds a {@link PropertyVisibilityListener} that gets notified when a property column is hidden or shown. * @param listener Listener to add (not null) * @return this */ B withPropertyVisibilityListener(PropertyVisibilityListener

listener); /** * Set the {@link ItemDescriptionGenerator} to use to generate item descriptions (tooltips). * @param rowDescriptionGenerator Generator to set (not null) * @return this */ B itemDescriptionGenerator(ItemDescriptionGenerator rowDescriptionGenerator); /** * Sets whether column hiding by user is allowed or not. * @param columnHidingAllowed true if column hiding is allowed * @return this */ B columnHidingAllowed(boolean columnHidingAllowed); /** * Sets whether column reordering is allowed or not. * @param columnReorderingAllowed true if column reordering is allowed * @return this */ B columnReorderingAllowed(boolean columnReorderingAllowed); /** * Set whether the listing footer is visible. * @param footerVisible whether the listing footer is visible * @return this */ B footerVisible(boolean footerVisible); /** * Build the {@link ItemListing} instance, setting given properties as visible columns. *

* Use {@link #build()} to build an {@link ItemListing} using all data source properties as visible columns. *

* @param visibleColumns Visible column properties (not null) * @return {@link ItemListing} component */ @SuppressWarnings("unchecked") default C build(P... visibleColumns) { ObjectUtils.argumentNotNull(visibleColumns, "Visible columns must be not null"); if (visibleColumns.length == 0) { throw new IllegalArgumentException("Visible columns must be not null and not empty"); } return build(Arrays.asList(visibleColumns)); } /** * Build the {@link ItemListing} instance, setting given properties as visible columns. *

* Use {@link #build()} to build an {@link ItemListing} using all data source properties as visible columns. *

* @param visibleColumns Visible column properties (not null) * @return {@link ItemListing} component */ C build(Iterable

visibleColumns); // Using Grid /** * Base builder to create an {@link ItemListing} with a {@link Grid} as backing component. * @param Item data type * @param

Item property type * @param Component type * @param Concrete builder type */ public interface BaseGridItemListingBuilder, B extends BaseGridItemListingBuilder> extends ItemListingBuilder { /** * Set the height of the listing defined by its contents. * @return this */ B heightByContents(); /** * Set the height of the listing by defined by a number of rows. * @param rows Number of rows that should be visible in grid's body * @return this */ B heightByRows(double rows); /** * Set the minimum width in pixels for the column which corresponds to given property. * @param property Item property to set the width for (not null) * @param widthInPixels Minimum width in pixel * @return this */ B minWidth(P property, int widthInPixels); /** * Set the maximum width in pixels for the column which corresponds to given property. * @param property Item property to set the width for (not null) * @param widthInPixels Maximum width in pixel * @return this */ B maxWidth(P property, int widthInPixels); /** * Set the expandRatio for the column which corresponds to given property. *

* By default, all columns expand equally (treated as if all of them had an expand ratio of 1). Once at least * one column gets a defined expand ratio, the implicit expand ratio is removed, and only the defined expand * ratios are taken into account. *

*

* If a column has a defined width, it overrides this method's effects. *

*

* Example: A grid with three columns, with expand ratios 0, 1 and 2, respectively. The column with a * ratio of 0 is exactly as wide as its contents requires. The column with a ratio of 1 is as * wide as it needs, plus a third of any excess space, because we have 3 parts total, and this * column reserves only one of those. The column with a ratio of 2, is as wide as it needs to be, plus * two thirds of the excess width. *

* @param property Item property to set the expand ratio for (not null) * @param expandRatio Column expand ratio. 0 to not have it expand at all * @return this */ B expandRatio(P property, int expandRatio); /** * Sets the caption of the hiding toggle for the column which corresponds to given property. Shown in the toggle * for this column in the grid's sidebar when the column is hidable. * @param property Item property to set the caption for (not null) * @param hidingToggleCaption Localizable hiding toggle caption (not null) * @return this */ B hidingToggleCaption(P property, Localizable hidingToggleCaption); /** * Sets the caption of the hiding toggle for the column which corresponds to given property. Shown in the toggle * for this column in the grid's sidebar when the column is hidable. * @param property Item property to set the caption for (not null) * @param hidingToggleCaption Hiding toggle caption * @return this */ default B hidingToggleCaption(P property, String hidingToggleCaption) { return hidingToggleCaption(property, Localizable.builder().message(hidingToggleCaption).build()); } /** * Sets the caption of the hiding toggle for the column which corresponds to given property. Shown in the toggle * for this column in the grid's sidebar when the column is hidable. * @param property Item property to set the caption for (not null) * @param hidingToggleCaption Hiding toggle caption default message * @param messageCode Hiding toggle caption localization message code * @return this */ default B hidingToggleCaption(P property, String hidingToggleCaption, String messageCode) { return hidingToggleCaption(property, Localizable.builder().message(hidingToggleCaption).messageCode(messageCode).build()); } /** * Sets whether the column which corresponds to given property is resizable by the user. * @param property Item property to set resizable or not (not null) * @param resizable true if the column which corresponds to given property is resizable by the user * @return this */ B resizable(P property, boolean resizable); /** * Sets the number of frozen columns in this listing. Setting the count to 0 means that no data columns will be * frozen, but the built-in selection checkbox column will still be frozen if it's in use. Setting the count to * -1 will also disable the selection column. * @param frozenColumnsCount The number of columns that should be frozen * @return this */ B frozenColumns(int frozenColumnsCount); /** * Set the caption for the editor Save button. * @param caption Localizable caption (not null) * @return this */ B editorSaveCaption(Localizable caption); /** * Set the caption for the editor Save button. * @param caption Button caption * @return this */ default B editorSaveCaption(String caption) { return editorSaveCaption(Localizable.builder().message(caption).build()); } /** * Set the caption for the editor Save button. * @param caption Button caption * @param messageCode Caption translation message code * @return this */ default B editorSaveCaption(String caption, String messageCode) { return editorSaveCaption(Localizable.builder().message(caption).messageCode(messageCode).build()); } /** * Set the caption for the editor Cancel button. * @param caption Localizable caption (not null) * @return this */ B editorCancelCaption(Localizable caption); /** * Set the caption for the editor Cancel button * @param caption Button caption * @return this */ default B editorCancelCaption(String caption) { return editorCancelCaption(Localizable.builder().message(caption).build()); } /** * Set the caption for the editor Cancel button * @param caption Button caption * @param messageCode Optional caption translation message code * @return this */ default B editorCancelCaption(String caption, String messageCode) { return editorCancelCaption(Localizable.builder().message(caption).messageCode(messageCode).build()); } /** * Sets to call {@link ItemListing#commit()} to confirm item modifications in data source when the editor * Save action is triggered. * @return this */ B commitOnSave(); /** * Sets to call {@link ItemListing#commit()} to confirm item modifications in data source when an item is * removed using {@link ItemListing#removeItem(Object)}. * @return this */ B commitOnRemove(); /** * Set the listing header builder to create and manage header rows. * @param builder Header builder (not null) * @return this */ B header(HeaderBuilder builder); /** * Set the listing footer builder to create and manage footer rows * @param builder Footer builder (not null) * @return this */ B footer(FooterBuilder builder); /** * Set a {@link GridFooterGenerator} to update footer contents when item set changes. * @param footerGenerator Footer generator * @return this */ B footerGenerator(GridFooterGenerator footerGenerator); /** * Set the {@link ItemDetailsGenerator} to generate row details component * @param detailsGenerator Item details generator (not null) * @return this */ B detailsGenerator(ItemDetailsGenerator detailsGenerator); } /** * Builder to create an {@link ItemListing} with a {@link Grid} as backing component. * @param Item data type */ public interface GridItemListingBuilder extends BaseGridItemListingBuilder, GridItemListingBuilder> { /** * Set a custom {@link Renderer} for given item property. * @param property Item property to set the renderer for (not null) * @param renderer Renderer to use * @return this */ GridItemListingBuilder render(String property, Renderer renderer); /** * Set a custom {@link Renderer} and {@link Converter} for given item property. * @param Property value type * @param

Presentation value type * @param property Item property to set the renderer for * @param converter Conveter to use * @param renderer Renderer to use * @return this */ GridItemListingBuilder render(String property, Converter converter, Renderer renderer); } // Using Table /** * Base builder to create an {@link ItemListing} with a {@link Table} as backing component. * @param Item data type * @param

Item property type * @param Component type * @param Concrete builder type */ public interface BaseTableItemListingBuilder, B extends BaseTableItemListingBuilder> extends ItemListingBuilder { /** * Set the expand ratio of the column which corresponds to given property. * @param property Item property to set the expand ratio for (not null) * @param expandRatio Column expand ratio * @return this */ B expandRatio(P property, float expandRatio); /** * Set the header icon for the column which corresponds to given property. * @param property Item property to set the icon for (not null) * @param icon Icon to set * @return this */ B icon(P property, Resource icon); /** * Set the table rows cache rate. *

* Table component may fetch and render some rows outside visible area. With complex tables (for example * containing layouts and components), the client side may become unresponsive. Setting the value lower, UI will * become more responsive. With higher values scrolling in client will hit server less frequently. *

*

* The amount of cached rows will be cacheRate multiplied with table {@link #pageLength(int)} both below and * above visible area. *

*

* Default cache rate is 1. *

* @param cacheRate a value over 0 (fastest rendering time). Higher value will cache more rows on server * (smoother scrolling). Default value is 2. * @return this */ B cacheRate(double cacheRate); /** * Sets the page length. *

* Setting page length 0 disables paging. *

*

* If Table has an height set the client side may update the page length automatically the correct value. *

* @param pageLength the length of one page * @return this */ B pageLength(int pageLength); /** * Set a {@link TableFooterGenerator} to generate table footer contents every time row set changes. * @param footerGenerator Footer contents generator (not null) * @return this */ B footer(TableFooterGenerator footerGenerator); /** * Adds a {@link HeaderClickListener} that gets notified when a column header is clicked. * @param listener Listener to add (not null) * @return this */ B withHeaderClickListener(HeaderClickListener listener); /** * Adds a {@link FooterClickListener} that gets notified when footer is clicked. * @param listener Listener to add (not null) * @return this */ B withFooterClickListener(FooterClickListener listener); /** * Sets the drag start mode of the Table. Drag start mode controls how Table behaves as a drag source. * @param dragMode Drag mode to set * @return this */ B dragMode(TableDragMode dragMode); /** * Set the handler to manage drops on table. * @param dropHandler Drop handler * @return this */ B dropHandler(DropHandler dropHandler); /** * Add an {@link Action} handler to table. * @param actionHandler Handler to add * @return this */ B withActionHandler(Action.Handler actionHandler); /** * Set the table row generator * @param rowGenerator Row generator to set * @return this */ B rowGenerator(RowGenerator rowGenerator); } /** * Builder to create an {@link ItemListing} with a {@link Table} as backing component. * @param Item data type */ public interface TableItemListingBuilder extends BaseTableItemListingBuilder, TableItemListingBuilder> { } // Support interfaces public interface GridSection> { /** * Add a section row at given index. * @param index Row index * @return Added row */ ROWTYPE addRowAt(int index); /** * Adds a new row at the bottom of the section. * @return the new row */ ROWTYPE appendRow(); /** * Get the section row at given index. * @param index Row index * @return Section row */ ROWTYPE getRowAt(int index); /** * Returns the current default row of the section. * @return the default row or null if no default row set */ ROWTYPE getDefaultRow(); /** * Gets the row count for the section. * @return row count */ int getRowCount(); /** * Adds a new row at the top of the section. * @return the new row */ ROWTYPE prependRow(); /** * Removes the given row from the section. * @param row the row to be removed */ void removeRow(ROWTYPE row); /** * Removes the row at the given position from the section. * @param rowIndex the position of the row */ void removeRow(int rowIndex); /** * Sets the default row of the section. * @param row the new default row, or null for no default row */ void setDefaultRow(ROWTYPE row); } /** * Builder to create and manage Header rows. */ @FunctionalInterface public interface HeaderBuilder { /** * Build Grid header rows. * @param header Header rows container */ void buildHeader(GridSection header); } /** * Builder to create and manage Footer rows. */ @FunctionalInterface public interface FooterBuilder { /** * Build Grid footer rows. * @param footer Footer rows container */ void buildFooter(GridSection footer); } /** * Generator for footer contents. */ @FunctionalInterface public interface TableFooterGenerator extends Serializable { /** * Generate the footer content for the column which corresponds to given property. * @param listing Source listing component * @param property Property to which the column is bound * @return Footer content, null for none */ String getFooter(ItemListing listing, P property); } /** * Generator for footer contents. */ @FunctionalInterface public interface GridFooterGenerator extends Serializable { /** * Updates the footer row contents. * @param listing Source listing component * @param footer Footer row reference */ void updateFooter(ItemListing listing, GridSection footer); } }