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);
}
}