package com.vaadin.tests.components.grid.basics;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Stream;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Widgetset;
import com.vaadin.data.Binder;
import com.vaadin.data.Binder.Binding;
import com.vaadin.data.converter.StringToIntegerConverter;
import com.vaadin.event.selection.MultiSelectionEvent;
import com.vaadin.event.selection.SingleSelectionEvent;
import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.Registration;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.grid.ColumnResizeMode;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.Label;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.MenuBar.Command;
import com.vaadin.ui.MenuBar.MenuItem;
import com.vaadin.ui.MultiSelect;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Panel;
import com.vaadin.ui.SingleSelect;
import com.vaadin.ui.StyleGenerator;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.components.grid.DetailsGenerator;
import com.vaadin.ui.components.grid.FooterCell;
import com.vaadin.ui.components.grid.FooterRow;
import com.vaadin.ui.components.grid.HeaderCell;
import com.vaadin.ui.components.grid.HeaderRow;
import com.vaadin.ui.components.grid.MultiSelectionModel;
import com.vaadin.ui.components.grid.MultiSelectionModel.SelectAllCheckBoxVisibility;
import com.vaadin.ui.components.grid.MultiSelectionModelImpl;
import com.vaadin.ui.components.grid.SingleSelectionModelImpl;
import com.vaadin.ui.renderers.DateRenderer;
import com.vaadin.ui.renderers.HtmlRenderer;
import com.vaadin.ui.renderers.NumberRenderer;
import com.vaadin.ui.renderers.ProgressBarRenderer;
@Widgetset("com.vaadin.DefaultWidgetSet")
@Theme("tests-valo-disabled-animations")
public class GridBasics extends AbstractTestUIWithLog {
public static final String ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4 = "Row numbers for 3/4";
public static final String ROW_STYLE_GENERATOR_NONE = "None";
public static final String ROW_STYLE_GENERATOR_ROW_NUMBERS = "Row numbers";
public static final String ROW_STYLE_GENERATOR_EMPTY = "Empty string";
public static final String ROW_STYLE_GENERATOR_NULL = "Null";
public static final String CELL_STYLE_GENERATOR_NONE = "None";
public static final String CELL_STYLE_GENERATOR_PROPERTY_TO_STRING = "Property to string";
public static final String CELL_STYLE_GENERATOR_SPECIAL = "Special for 1/4 Column 1";
public static final String CELL_STYLE_GENERATOR_EMPTY = "Empty string";
public static final String CELL_STYLE_GENERATOR_NULL = "Null";
private boolean isUserSelectionDisallowed;
public static final String[] COLUMN_CAPTIONS = { "Column 0", "Column 1",
"Column 2", "Row Number", "Date", "HTML String", "Big Random",
"Small Random" };
private final Command toggleReorderListenerCommand = new Command() {
private Registration registration = null;
@Override
public void menuSelected(MenuItem selectedItem) {
removeRegistration();
if (selectedItem.isChecked()) {
registration = grid.addColumnReorderListener(event -> {
List<String> columnCaptions = new ArrayList<>();
for (Column<DataObject, ?> column : grid.getColumns()) {
columnCaptions.add(column.getCaption());
}
log("Columns reordered, userOriginated: "
+ event.isUserOriginated());
log("Column order: " + columnCaptions.toString());
});
log("Registered a column reorder listener.");
}
}
private void removeRegistration() {
if (registration != null) {
registration.remove();
registration = null;
log("Removed a column reorder listener.");
}
}
};
private static class DetailedDetailsGenerator
implements DetailsGenerator<DataObject> {
@Override
public Component apply(DataObject dataObj) {
VerticalLayout cssLayout = new VerticalLayout();
cssLayout.setHeight("200px");
cssLayout.setWidth("100%");
cssLayout.addComponent(
new Label("Row Number: " + dataObj.getRowNumber()));
cssLayout.addComponent(new Label("Date: " + dataObj.getDate()));
cssLayout.addComponent(
new Label("Big Random: " + dataObj.getBigRandom()));
cssLayout.addComponent(
new Label("Small Random: " + dataObj.getSmallRandom()));
cssLayout
.addComponent(new Button("Press me",
e -> Notification.show("You clicked on the "
+ "button in the details for " + "row "
+ dataObj.getRowNumber())));
return cssLayout;
}
}
private static class PersistingDetailsGenerator
implements DetailsGenerator<DataObject> {
private Map<DataObject, Panel> detailsMap = new HashMap<>();
@Override
public Component apply(DataObject dataObj) {
if (!detailsMap.containsKey(dataObj)) {
Panel panel = new Panel();
panel.setContent(new Label("One"));
detailsMap.put(dataObj, panel);
}
return detailsMap.get(dataObj);
}
public void changeDetailsComponent(MenuItem item) {
for (DataObject id : detailsMap.keySet()) {
Panel panel = detailsMap.get(id);
Label label = (Label) panel.getContent();
if (label.getValue().equals("One")) {
panel.setContent(new Label("Two"));
} else {
panel.setContent(new Label("One"));
}
}
}
}
private Grid<DataObject> grid;
private Map<String, DetailsGenerator<DataObject>> generators = new LinkedHashMap<>();
private List<DataObject> data;
private int watchingCount = 0;
private PersistingDetailsGenerator persistingDetails;
private List<Column<DataObject, ?>> initialColumnOrder;
private Registration selectionListenerRegistration;
public GridBasics() {
generators.put("NULL", null);
generators.put("Detailed", new DetailedDetailsGenerator());
generators
.put("\"Watching\"",
dataObj -> new Label("You are watching item id "
+ dataObj.getRowNumber() + " ("
+ watchingCount++ + ")"));
persistingDetails = new PersistingDetailsGenerator();
generators.put("Persisting", persistingDetails);
}
@Override
protected void setup(VaadinRequest request) {
data = DataObject.generateObjects();
VerticalLayout layout = new VerticalLayout();
layout.setSpacing(true);
layout.setSizeFull();
// Create grid
grid = new Grid<>();
grid.setItems(data);
grid.setSizeFull();
Binder<DataObject> binder = grid.getEditor().getBinder();
TextField html = new TextField();
TextField smallRandom = new TextField();
TextField coordinates = new TextField();
TextField rowNumber = new TextField();
Binding<DataObject, Integer> smallRandomBinding = binder
.forField(smallRandom)
.withConverter(new StringToIntegerConverter(
"Could not convert value to Integer"))
.withValidator(i -> i >= 0 && i < 5,
"Small random needs to be in range [0..5)")
.bind(DataObject::getSmallRandom, DataObject::setSmallRandom);
Binding<DataObject, Integer> rowNumberBinding = binder
.forField(rowNumber)
.withConverter(new StringToIntegerConverter(
"Could not convert value to Integer"))
.bind(DataObject::getRowNumber, DataObject::setRowNumber);
grid.addColumn(DataObject::getCoordinates)
.setCaption(COLUMN_CAPTIONS[0])
.setEditorComponent(coordinates, DataObject::setCoordinates);
grid.addColumn(dataObj -> "(" + dataObj.getRowNumber() + ", 1)")
.setCaption(COLUMN_CAPTIONS[1]);
grid.addColumn(dataObj -> "(" + dataObj.getRowNumber() + ", 2)")
.setCaption(COLUMN_CAPTIONS[2]);
grid.addColumn(DataObject::getRowNumber, new NumberRenderer())
.setCaption(COLUMN_CAPTIONS[3])
.setEditorBinding(rowNumberBinding);
grid.addColumn(DataObject::getDate, new DateRenderer())
.setCaption(COLUMN_CAPTIONS[4]);
grid.addColumn(DataObject::getHtmlString, new HtmlRenderer())
.setCaption(COLUMN_CAPTIONS[5])
.setEditorComponent(html, DataObject::setHtmlString);
grid.addColumn(DataObject::getBigRandom, new NumberRenderer())
.setCaption(COLUMN_CAPTIONS[6]);
grid.addColumn(data -> data.getSmallRandom() / 5d,
new ProgressBarRenderer()).setCaption(COLUMN_CAPTIONS[7])
.setEditorBinding(smallRandomBinding);
selectionListenerRegistration = ((SingleSelectionModelImpl<DataObject>) grid
.getSelectionModel())
.addSingleSelectionListener(this::onSingleSelect);
grid.addColumnResizeListener(
event -> log("ColumnResizeEvent: isUserOriginated? "
+ event.isUserOriginated()));
grid.addSortListener(event -> log(
"SortEvent: isUserOriginated? " + event.isUserOriginated()));
layout.addComponent(
createMenu());
layout.addComponent(grid);
addComponent(layout);
}
private void onSingleSelect(SingleSelectionEvent<DataObject> event) {
log("SingleSelectionEvent: Selected: "
+ (event.getSelectedItem().isPresent()
? event.getSelectedItem().get().toString() : "none"));
}
private void onMultiSelect(MultiSelectionEvent<DataObject> event) {
Optional<DataObject> firstAdded = event.getAddedSelection().stream()
.findFirst();
Optional<DataObject> firstRemoved = event.getRemovedSelection().stream()
.findFirst();
String addedRow = firstAdded.isPresent() ? firstAdded.get().toString()
: "none";
String removedRow = firstRemoved.isPresent()
? firstRemoved.get().toString() : "none";
log("SelectionEvent: Added " + addedRow + ", Removed " + removedRow);
}
private Component createMenu() {
MenuBar menu = new MenuBar();
menu.setErrorHandler(error -> log("Exception occured, "
+ error.getThrowable().getClass().getName() + ": "
+ error.getThrowable().getMessage()));
MenuItem componentMenu = menu.addItem("Component", null);
createStateMenu(componentMenu.addItem("State", null));
createSizeMenu(componentMenu.addItem("Size", null));
createDetailsMenu(componentMenu.addItem("Details", null));
createBodyMenu(componentMenu.addItem("Body rows", null));
createHeaderMenu(componentMenu.addItem("Header", null));
createFooterMenu(componentMenu.addItem("Footer", null));
createColumnsMenu(componentMenu.addItem("Columns", null));
createEditorMenu(componentMenu.addItem("Editor", null));
return menu;
}
@SuppressWarnings("unchecked")
private void createColumnsMenu(MenuItem columnsMenu) {
for (Column<DataObject, ?> col : grid.getColumns()) {
MenuItem columnMenu = columnsMenu.addItem(col.getCaption(), null);
columnMenu.addItem("Move left", selectedItem -> {
int index = grid.getColumns().indexOf(col);
if (index > 0) {
List<Column<DataObject, ?>> columnOrder = new ArrayList<>(
grid.getColumns());
Collections.swap(columnOrder, index, index - 1);
grid.setColumnOrder(columnOrder
.toArray(new Column[columnOrder.size()]));
}
});
columnMenu.addItem("Move right", selectedItem -> {
int index = grid.getColumns().indexOf(col);
if (index < grid.getColumns().size() - 1) {
List<Column<DataObject, ?>> columnOrder = new ArrayList<>(
grid.getColumns());
Collections.swap(columnOrder, index, index + 1);
grid.setColumnOrder(columnOrder
.toArray(new Column[columnOrder.size()]));
}
});
MenuItem headerTypeMenu = columnMenu.addItem("Header Type", null);
headerTypeMenu.addItem("Text Header", selectedItem -> grid
.getDefaultHeaderRow().getCell(col).setText("Text Header"));
headerTypeMenu.addItem("HTML Header",
selectedItem -> grid.getDefaultHeaderRow().getCell(col)
.setHtml("<b>HTML Header</b>"));
headerTypeMenu.addItem("Widget Header", selectedItem -> {
final Button button = new Button("Button Header");
button.addClickListener(clickEvent -> log("Button clicked!"));
grid.getDefaultHeaderRow().getCell(col).setComponent(button);
});
MenuItem footerTypeMenu = columnMenu.addItem("Footer Type", null);
footerTypeMenu.addItem("Text Footer", selectedItem -> grid
.getFooterRow(0).getCell(col).setText("Text Footer"));
footerTypeMenu.addItem("HTML Footer",
selectedItem -> grid.getFooterRow(0).getCell(col)
.setHtml("<b>HTML Footer</b>"));
footerTypeMenu.addItem("Widget Footer", selectedItem -> {
final Button button = new Button("Button Footer");
button.addClickListener(clickEvent -> log("Button clicked!"));
grid.getFooterRow(0).getCell(col).setComponent(button);
});
columnMenu
.addItem("Sortable",
selectedItem -> col
.setSortable(selectedItem.isChecked()))
.setCheckable(true);
columnMenu
.addItem("Hidable",
selectedItem -> col
.setHidable(selectedItem.isChecked()))
.setCheckable(true);
columnMenu
.addItem("Hidden",
selectedItem -> col
.setHidden(selectedItem.isChecked()))
.setCheckable(true);
columnMenu.addItem("Remove",
selectedItem -> grid.removeColumn(col));
columnMenu.addItem("Sort ASC", item -> grid.sort(col));
columnMenu.addItem("Sort DESC",
item -> grid.sort(col, SortDirection.DESCENDING));
}
columnsMenu.addItem("Clear sort", item -> grid.clearSortOrder());
columnsMenu.addItem("Simple resize mode",
item -> grid.setColumnResizeMode(item.isChecked()
? ColumnResizeMode.SIMPLE : ColumnResizeMode.ANIMATED))
.setCheckable(true);
}
private void createSizeMenu(MenuItem sizeMenu) {
MenuItem heightByRows = sizeMenu.addItem("Height by Rows", null);
DecimalFormat df = new DecimalFormat("0.00");
Stream.of(0.33, 0.67, 1.00, 1.33, 1.67, 2.00, 2.33, 2.67, 3.00, 3.33,
3.67, 4.00, 4.33, 4.67)
.forEach(d -> addGridMethodMenu(heightByRows,
df.format(d) + " rows", d, grid::setHeightByRows));
sizeMenu.addItem("HeightMode Row", item -> {
grid.setHeightMode(
item.isChecked() ? HeightMode.ROW : HeightMode.CSS);
}).setCheckable(true);
MenuItem heightMenu = sizeMenu.addItem("Height", null);
Stream.of(50, 100, 200, 400).map(i -> i + "px").forEach(
i -> addGridMethodMenu(heightMenu, i, i, grid::setHeight));
MenuItem rowHeightMenu = sizeMenu.addItem("Row Height", null);
Stream.of(-1, 20, 40, 100).forEach(i -> addGridMethodMenu(rowHeightMenu,
String.valueOf(i), (double) i, grid::setRowHeight));
}
private void createStateMenu(MenuItem stateMenu) {
MenuItem tabIndexMenu = stateMenu.addItem("Tab index", null);
addGridMethodMenu(tabIndexMenu, "0", 0, grid::setTabIndex);
addGridMethodMenu(tabIndexMenu, "-1", -1, grid::setTabIndex);
addGridMethodMenu(tabIndexMenu, "10", 10, grid::setTabIndex);
MenuItem frozenColMenu = stateMenu.addItem("Frozen column count", null);
for (int i = -1; i < 3; ++i) {
addGridMethodMenu(frozenColMenu, "" + i, i,
grid::setFrozenColumnCount);
}
createRowStyleMenu(stateMenu.addItem("Row style generator", null));
createCellStyleMenu(stateMenu.addItem("Cell style generator", null));
stateMenu.addItem("Row description generator",
item -> grid.setDescriptionGenerator(item.isChecked()
? t -> "Row tooltip for row " + t.getRowNumber()
: null))
.setCheckable(true);
stateMenu
.addItem("Cell description generator", item -> grid.getColumns()
.stream().findFirst()
.ifPresent(c -> c.setDescriptionGenerator(
item.isChecked() ? t -> "Cell tooltip for row "
+ t.getRowNumber() + ", Column 0"
: null)))
.setCheckable(true);
stateMenu.addItem("Item click listener", new Command() {
private Registration registration = null;
@Override
public void menuSelected(MenuItem selectedItem) {
removeRegistration();
if (selectedItem.isChecked()) {
registration = grid.addItemClickListener(e -> {
grid.setDetailsVisible(e.getItem(),
!grid.isDetailsVisible(e.getItem()));
log("Item click on row " + e.getItem().getRowNumber()
+ ", Column '" + e.getColumn().getCaption()
+ "'");
});
log("Registered an item click listener.");
}
}
private void removeRegistration() {
if (registration != null) {
registration.remove();
registration = null;
log("Removed an item click listener.");
}
}
}).setCheckable(true);
MenuItem selectionAllowedItem = stateMenu
.addItem("Disallow user selection", item -> {
isUserSelectionDisallowed = !isUserSelectionDisallowed;
if (grid.getSelectionModel() instanceof MultiSelectionModelImpl) {
MultiSelect<DataObject> multiSelect = grid
.asMultiSelect();
multiSelect.setReadOnly(isUserSelectionDisallowed);
}
if (grid.getSelectionModel() instanceof SingleSelectionModelImpl) {
SingleSelect<DataObject> singleSelect = grid
.asSingleSelect();
singleSelect.setReadOnly(isUserSelectionDisallowed);
}
});
selectionAllowedItem.setChecked(false);
selectionAllowedItem.setCheckable(true);
stateMenu.addItem("Column reorder listener",
toggleReorderListenerCommand).setCheckable(true);
stateMenu
.addItem("Column Reordering", selectedItem -> grid
.setColumnReorderingAllowed(selectedItem.isChecked()))
.setCheckable(true);
MenuItem enableItem = stateMenu.addItem("Enabled",
e -> grid.setEnabled(e.isChecked()));
enableItem.setCheckable(true);
enableItem.setChecked(true);
createSelectionMenu(stateMenu);
stateMenu.addItem("Set focus", item -> grid.focus());
}
private void createRowStyleMenu(MenuItem rowStyleMenu) {
addGridMethodMenu(rowStyleMenu, ROW_STYLE_GENERATOR_NONE,
(StyleGenerator<DataObject>) t -> null,
grid::setStyleGenerator);
addGridMethodMenu(rowStyleMenu, ROW_STYLE_GENERATOR_ROW_NUMBERS,
t -> "row" + t.getRowNumber(), grid::setStyleGenerator);
addGridMethodMenu(rowStyleMenu,
ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4,
t -> t.getRowNumber() % 4 != 0 ? "row" + t.getRowNumber()
: null,
grid::setStyleGenerator);
addGridMethodMenu(rowStyleMenu, ROW_STYLE_GENERATOR_EMPTY, t -> "",
grid::setStyleGenerator);
addGridMethodMenu(rowStyleMenu, ROW_STYLE_GENERATOR_NULL, t -> null,
grid::setStyleGenerator);
}
private void createCellStyleMenu(MenuItem cellStyleMenu) {
addGridMethodMenu(cellStyleMenu, CELL_STYLE_GENERATOR_NONE,
(StyleGenerator<DataObject>) t -> null,
sg -> grid.getColumns().forEach(c -> c.setStyleGenerator(sg)));
addGridMethodMenu(cellStyleMenu, CELL_STYLE_GENERATOR_EMPTY,
(StyleGenerator<DataObject>) t -> "",
sg -> grid.getColumns().forEach(c -> c.setStyleGenerator(sg)));
addGridMethodMenu(cellStyleMenu,
CELL_STYLE_GENERATOR_PROPERTY_TO_STRING,
(StyleGenerator<DataObject>) t -> null,
sg -> grid.getColumns().forEach(c -> c.setStyleGenerator(
t -> c.getCaption().replaceAll(" ", "-"))));
addGridMethodMenu(cellStyleMenu, CELL_STYLE_GENERATOR_SPECIAL,
(StyleGenerator<DataObject>) t -> null,
sg -> grid.getColumns().forEach(c -> c.setStyleGenerator(t -> {
if (t.getRowNumber() % 4 == 1) {
return null;
} else if (t.getRowNumber() % 4 == 3
&& c.getCaption().equals("Column 1")) {
return null;
}
return c.getCaption().replaceAll(" ", "_");
})));
addGridMethodMenu(cellStyleMenu, CELL_STYLE_GENERATOR_NULL,
(StyleGenerator<DataObject>) t -> null,
sg -> grid.getColumns().forEach(c -> c.setStyleGenerator(sg)));
}
private <T> void addGridMethodMenu(MenuItem parent, String name, T value,
Consumer<T> method) {
parent.addItem(name, menuItem -> method.accept(value));
}
private void createBodyMenu(MenuItem rowMenu) {
rowMenu.addItem("Toggle first row selection", menuItem -> {
DataObject item = data.get(0);
if (grid.getSelectionModel().isSelected(item)) {
grid.getSelectionModel().deselect(item);
} else {
grid.getSelectionModel().select(item);
}
});
rowMenu.addItem("Deselect all", menuItem -> {
grid.getSelectionModel().deselectAll();
});
}
private void createSelectionMenu(MenuItem stateItem) {
MenuItem selectionModelItem = stateItem.addItem("Selection model",
null);
selectionModelItem.addItem("single", menuItem -> {
selectionListenerRegistration.remove();
grid.setSelectionMode(SelectionMode.SINGLE);
selectionListenerRegistration = ((SingleSelectionModelImpl<DataObject>) grid
.getSelectionModel())
.addSingleSelectionListener(this::onSingleSelect);
grid.asSingleSelect().setReadOnly(isUserSelectionDisallowed);
});
selectionModelItem.addItem("multi", menuItem -> {
switchToMultiSelect();
});
selectionModelItem.addItem("none", menuItem -> {
selectionListenerRegistration.remove();
grid.setSelectionMode(SelectionMode.NONE);
});
selectionModelItem.addItem("Select All", menuItem -> {
switchToMultiSelect();
((MultiSelectionModel<DataObject>) grid.getSelectionModel())
.selectAll();
});
selectionModelItem.addItem("Deselect All", menuItem -> {
switchToMultiSelect();
((MultiSelectionModel<DataObject>) grid.getSelectionModel())
.deselectAll();
});
selectionModelItem.addItem("SelectAllCheckbox: Visible", menuItem -> {
switchToMultiSelect();
((MultiSelectionModelImpl<DataObject>) grid.getSelectionModel())
.setSelectAllCheckBoxVisibility(
SelectAllCheckBoxVisibility.VISIBLE);
});
selectionModelItem.addItem("SelectAllCheckbox: Hidden", menuItem -> {
switchToMultiSelect();
((MultiSelectionModelImpl<DataObject>) grid.getSelectionModel())
.setSelectAllCheckBoxVisibility(
SelectAllCheckBoxVisibility.HIDDEN);
});
selectionModelItem.addItem("SelectAllCheckbox: Default", menuItem -> {
switchToMultiSelect();
((MultiSelectionModelImpl<DataObject>) grid.getSelectionModel())
.setSelectAllCheckBoxVisibility(
SelectAllCheckBoxVisibility.DEFAULT);
});
}
private void switchToMultiSelect() {
if (!(grid.getSelectionModel() instanceof MultiSelectionModel)) {
selectionListenerRegistration.remove();
MultiSelectionModelImpl<DataObject> model = (MultiSelectionModelImpl<DataObject>) grid
.setSelectionMode(SelectionMode.MULTI);
model.addMultiSelectionListener(this::onMultiSelect);
grid.asMultiSelect().setReadOnly(isUserSelectionDisallowed);
selectionListenerRegistration = model
.addMultiSelectionListener(this::onMultiSelect);
}
}
private void createHeaderMenu(MenuItem headerMenu) {
headerMenu.addItem("Append header row", menuItem -> {
HeaderRow row = grid.appendHeaderRow();
int i = 0;
for (Column<?, ?> column : grid.getColumns()) {
row.getCell(column).setText("Header cell " + i++);
}
});
headerMenu.addItem("Prepend header row", menuItem -> {
HeaderRow row = grid.prependHeaderRow();
int i = 0;
for (Column<?, ?> column : grid.getColumns()) {
row.getCell(column).setText("Header cell " + i++);
}
});
headerMenu.addItem("Remove first header row", menuItem -> {
grid.removeHeaderRow(0);
});
headerMenu.addItem("Set first row as default", menuItem -> {
grid.setDefaultHeaderRow(grid.getHeaderRow(0));
});
headerMenu.addItem("Set no default row", menuItem -> {
grid.setDefaultHeaderRow(null);
});
headerMenu.addItem("Merge Header Cells [0,0..1]", menuItem -> {
mergeHeaderСells(0, "0+1", 0, 1);
});
headerMenu.addItem("Merge Header Cells [1,1..3]", menuItem -> {
mergeHeaderСells(1, "1+2+3", 1, 2, 3);
});
headerMenu.addItem("Merge Header Cells [0,6..7]", menuItem -> {
mergeHeaderСells(0, "6+7", 6, 7);
});
}
private void mergeHeaderСells(int rowIndex, String jointCellText,
int... columnIndexes) {
HeaderRow headerRow = grid.getHeaderRow(rowIndex);
List<Column<DataObject, ?>> columns = grid.getColumns();
Set<HeaderCell> toMerge = new HashSet<>();
for (int columnIndex : columnIndexes) {
toMerge.add(headerRow.getCell(columns.get(columnIndex)));
}
headerRow.join(toMerge).setText(jointCellText);
}
private void mergeFooterСells(int rowIndex, String jointCellText,
int... columnIndexes) {
FooterRow footerRow = grid.getFooterRow(rowIndex);
List<Column<DataObject, ?>> columns = grid.getColumns();
Set<FooterCell> toMerge = new HashSet<>();
for (int columnIndex : columnIndexes) {
toMerge.add(footerRow.getCell(columns.get(columnIndex)));
}
footerRow.join(toMerge).setText(jointCellText);
}
private void createFooterMenu(MenuItem footerMenu) {
footerMenu.addItem("Add default footer row", menuItem -> {
FooterRow defaultFooter = grid.appendFooterRow();
grid.getColumns().forEach(
column -> defaultFooter.getCell(column).setText(grid
.getDefaultHeaderRow().getCell(column).getText()));
footerMenu.removeChild(menuItem);
});
footerMenu.addItem("Append footer row", menuItem -> {
FooterRow row = grid.appendFooterRow();
int i = 0;
for (Column<?, ?> column : grid.getColumns()) {
row.getCell(column).setText("Footer cell " + i++);
}
});
footerMenu.addItem("Prepend footer row", menuItem -> {
FooterRow row = grid.prependFooterRow();
int i = 0;
for (Column<?, ?> column : grid.getColumns()) {
row.getCell(column).setText("Footer cell " + i++);
}
});
footerMenu.addItem("Remove first footer row", menuItem -> {
grid.removeFooterRow(0);
});
footerMenu.addItem("Merge Footer Cells [0,0..1]", menuItem -> {
mergeFooterСells(0, "0+1", 0, 1);
});
footerMenu.addItem("Merge Footer Cells [1,1..3]", menuItem -> {
mergeFooterСells(1, "1+2+3", 1, 2, 3);
});
footerMenu.addItem("Merge Footer Cells [0,6..7]", menuItem -> {
mergeFooterСells(0, "6+7", 6, 7);
});
}
/* DetailsGenerator related things */
private void createDetailsMenu(MenuItem detailsMenu) {
MenuItem generatorsMenu = detailsMenu.addItem("Generators", null);
generators.forEach((name, gen) -> generatorsMenu.addItem(name,
item -> grid.setDetailsGenerator(gen)));
generatorsMenu.addItem("- Change Component",
persistingDetails::changeDetailsComponent);
detailsMenu.addItem("Toggle First", item -> {
DataObject first = data.get(0);
openOrCloseDetails(first);
openOrCloseDetails(first);
});
detailsMenu.addItem("Open First", item -> {
DataObject object = data.get(0);
openOrCloseDetails(object);
});
detailsMenu.addItem("Open 1", item -> {
DataObject object = data.get(1);
openOrCloseDetails(object);
});
detailsMenu.addItem("Open 995", item -> {
DataObject object = data.get(995);
openOrCloseDetails(object);
});
}
private void createEditorMenu(MenuItem editorMenu) {
editorMenu
.addItem("Enabled",
i -> grid.getEditor().setEnabled(i.isChecked()))
.setCheckable(true);
MenuItem bufferedMode = editorMenu.addItem("Buffered mode",
i -> grid.getEditor().setBuffered(i.isChecked()));
bufferedMode.setCheckable(true);
bufferedMode.setChecked(true);
editorMenu.addItem("Save", i -> grid.getEditor().save());
editorMenu.addItem("Cancel edit", i -> grid.getEditor().cancel());
editorMenu.addItem("Change save caption",
e -> grid.getEditor().setSaveCaption("ǝʌɐS"));
editorMenu.addItem("Change cancel caption",
e -> grid.getEditor().setCancelCaption("ʃǝɔuɐↃ"));
}
private void openOrCloseDetails(DataObject dataObj) {
grid.setDetailsVisible(dataObj, !grid.isDetailsVisible(dataObj));
}
}