ComponentRenderer
A ComponentRenderer for the Vaadin Grid
ComponentRenderer
CAUTION!!! Does NOT support Vaadin 8 Grid. Only Vaadin 7 compatibility Grid. Version 2.0.0 runs with Vaadin 8 but is only compatible with Vaadin 8 V7 compatibility layer components. For Vaadin 7 you can still use the latest 1.X.X Version which is stable.
Vaadin 8.1 supports components out-of-the box: https://demo.vaadin.com/sampler/#ui/grids-and-trees/grid/component-renderer
Renders standard Vaadin components in the grid.
Online Demo User: demo Pw: demo
For a full description see the Readme
For usage, look at the demo-source-code: Link to Source-Code of the Demo UI
Features
- Plain Java server side coding, as usual
- Standard Tooltips work
- Components can be combined in layouts (e.g. multiple images in a horizontal layout)
- Works with static columns, generated columns or Converters
- Standard ValueChange/ClickListeners
- Supports Keyboard-Navigation (ENTER focuses the component inside the cell or its input field if it has one, ESC switches the focus back to the surrounding cell, so navigating through the grid with the arrow keys can continue)
- Open and Close the row-details with CTRL + DOWN and CTRL + UP
- Preserve the grid focus on manual triggered refresh
- HeaderGenerator to easily set column headers e.g. from ResourceBundles
- creates component editor fields for the grid editor
Limitations
- Components inside a cell should have fixed sizes, otherwise all browsers expect Chrome do lots of measurements and relayout which slows down rendering
Bugs & Features
Please report bugs or feature-wishes in the github issue-tracker to further improve this renderer.
Use the renderer
Add the maven dependency to your pom then recompile the widgetset.
Demo Application
Have a look at the demo app, you can start it with:
cd componentrenderer-demo
mvn jetty:run
Sample code
Grid grid = new Grid(); addComponent(createEnableDisableCheckBox(grid)); ComponentCellKeyExtension.extend(grid); focusPreserveExtension = FocusPreserveExtension.extend(grid); DetailsKeysExtension.extend(grid); grid.setWidth(100, Unit.PERCENTAGE); grid.setHeight(100, Unit.PERCENTAGE); // Initialize Containers BeanItemContainer<Customer> bc = new BeanItemContainer<Customer>(Customer.class); GeneratedPropertyContainer gpc = new GeneratedPropertyContainer(bc); grid.setContainerDataSource(gpc); // Load the data bc.addAll(createDummyData()); // Initialize DetailsGenerator (Caution: the DetailsGenerator is set to null // when grid#setContainerDatasource is called, so make sure you call setDetailsGenerator // after setContainerDatasource grid.setDetailsGenerator(rowReference -> { VerticalLayout layout = new VerticalLayout(); layout.setHeight(100, Unit.PIXELS); layout.addComponent(new Label(((Customer) rowReference.getItemId()).getFirstName())); return layout; }); gpc.addGeneratedProperty(FOOD, new PropertyValueGenerator<Component>() { @Override public Component getValue(Item item, Object itemId, Object propertyId) { return createFoodSelector(grid, (Customer) itemId); } @Override public Class<Component> getType() { return Component.class; } // You must override getSortProperties to allow sorting by the values // underlying of the GeneratedValue. The default is that generated // property columns cannot be sorted (see PropertyValueGenerator default implementation) // if the generated column is not shadowing a real data column DO NOT overwrite this method // otherwise an exception is thrown when you sort it because the bean property cannot be found @Override public SortOrder[] getSortProperties(SortOrder order) { return new SortOrder[]{order}; } }); // Don't forget to set the ComponentRenderer AFTER adding the column grid.getColumn(FOOD).setRenderer(new ComponentRenderer());
ComponentGrid<Customer> grid = new ComponentGrid<>(Customer.class); grid.setWidth(100, Unit.PERCENTAGE); grid.setHeight(70, Unit.PERCENTAGE); grid.setRows(createDummyData()); grid.setDetailsGenerator(rowReference -> { VerticalLayout layout = new VerticalLayout(); layout.setHeight(100, Unit.PIXELS); layout.addComponent(new Label(((Customer)rowReference.getItemId()).getFirstName())); return layout; }); grid.addComponentColumn(FOOD, cust -> createFoodSelector(grid, cust)); grid.addComponentColumn(FOOD_ICON, cust -> createFoodIcon(cust)); grid.addComponentColumn(RATING, cust -> createRating(cust)); grid.addComponentColumn(DELETE, cust -> createDeleteButton(grid, cust)); grid.addComponentColumn(DETAILS_ICONS, cust -> createDetailsIcons(grid, cust)); grid.setFrozenColumnCount(1); grid.setColumns(DETAILS_ICONS, ID, FIRST_NAME, LAST_NAME, FOOD, FOOD_ICON, RATING, DELETE); layout.addComponent(grid);
Grid grid = new Grid(); grid.setContainerDataSource(new BeanItemContainer<Customer>(Customer.class)); ComponentGridDecorator<Customer> componentGridDecorator = new ComponentGridDecorator<>(grid, Customer.class); componentGridDecorator.addAll(CustomerProvider.createDummyData()); addComponent(ViewComponents.createEnableDisableCheckBox(grid)); grid.setSizeFull(); // Initialize DetailsGenerator (Caution: the DetailsGenerator is set to null // when grid#setContainerDatasource is called, so make sure you call setDetailsGenerator // after setContainerDatasource grid.setDetailsGenerator(new CustomerDetailsGenerator()); componentGridDecorator.addComponentColumn(Customer.FOOD, cust -> ViewComponents.createFoodSelector(componentGridDecorator, cust)); componentGridDecorator.addComponentColumn(GENERATED_FOOD_ICON, cust -> ViewComponents.createFoodIcon(cust)); componentGridDecorator.addComponentColumn(GENERATED_RATING, cust -> ViewComponents.createRating(cust)); componentGridDecorator.addComponentColumn(GENERATED_DELETE, cust -> ViewComponents.createDeleteButton(componentGridDecorator, cust)); componentGridDecorator.addComponentColumn(GENERATED_DETAILS_ICONS, cust -> ViewComponents.createDetailsIcons(grid, cust)); // always display the details column grid.setFrozenColumnCount(1); grid.setColumns(GENERATED_DETAILS_ICONS, Customer.ID, Customer.FIRST_NAME, Customer.LAST_NAME, Customer.FOOD, GENERATED_FOOD_ICON, GENERATED_RATING, GENERATED_DELETE); addComponent(grid);
Links
Compatibility
Was this helpful? Need more help?
Leave a comment or a question below. You can also join
the chat on Discord or
ask questions on StackOverflow.
Version
Migrate to Vaadin 8 with compatibility layer. CAUTION this version is still experimental!
- Released
- 2017-02-24
- Maturity
- BETA
- License
- Apache License 2.0
Compatibility
- Framework
- Vaadin 8.0+
- Vaadin 7.5+ in 0.1.0
- Vaadin 7.6+ in 0.1.4
- Browser
- Firefox
- Opera
- Google Chrome
- Internet Explorer