Columns can be resized in two ways, with a helper or live.
<h:form id="form">
<p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true"/>
<div class="card">
<h5 style="margin-top:0">Basic Resize</h5>
<p:dataTable id="products1" var="product" value="#{dtResizableColumnsView.products1}"
resizableColumns="true" showGridlines="true">
<p:column headerText="Code">
<h:outputText value="#{product.code}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{product.name}" />
</p:column>
<p:column headerText="Category">
<h:outputText value="#{product.category}" />
</p:column>
<p:column headerText="Quantity">
<h:outputText value="#{product.quantity}" />
</p:column>
</p:dataTable>
</div>
<div class="card">
<h5>Live Resize with Callback</h5>
<p:dataTable id="products2" var="product" value="#{dtResizableColumnsView.products2}"
resizableColumns="true" liveResize="true" showGridlines="true">
<p:ajax event="colResize" update=":form:msgs" listener="#{dtResizableColumnsView.onResize}"/>
<p:column headerText="Code">
<h:outputText value="#{product.code}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{product.name}" />
</p:column>
<p:column headerText="Category">
<h:outputText value="#{product.category}" />
</p:column>
<p:column headerText="Quantity">
<h:outputText value="#{product.quantity}" />
</p:column>
</p:dataTable>
</div>
<div class="card">
<h5>Expand Mode with Grouping</h5>
<p:dataTable var="sale" value="#{dtGroupView.sales}" resizableColumns="true" resizeMode="expand"
showGridlines="true">
<p:columnGroup type="header">
<p:row>
<p:column rowspan="3" headerText="Product"/>
<p:column colspan="4" headerText="Sale Rate"/>
</p:row>
<p:row>
<p:column colspan="2" headerText="Sales"/>
<p:column colspan="2" headerText="Profit"/>
</p:row>
<p:row>
<p:column headerText="Last Year"/>
<p:column headerText="This Year"/>
<p:column headerText="Last Year"/>
<p:column headerText="This Year"/>
</p:row>
</p:columnGroup>
<p:column>
<h:outputText value="#{sale.manufacturer}"/>
</p:column>
<p:column>
<h:outputText value="#{sale.lastYearProfit}%"/>
</p:column>
<p:column>
<h:outputText value="#{sale.thisYearProfit}%"/>
</p:column>
<p:column>
<h:outputText value="#{sale.lastYearSale}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</p:column>
<p:column>
<h:outputText value="#{sale.thisYearSale}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</p:column>
<p:columnGroup type="footer">
<p:row>
<p:column colspan="3" style="text-align:right" footerText="Totals:"/>
<p:column>
<f:facet name="footer">
<h:outputText value="#{dtGroupView.lastYearTotal}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</f:facet>
</p:column>
<p:column>
<f:facet name="footer">
<h:outputText value="#{dtGroupView.thisYearTotal}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</f:facet>
</p:column>
</p:row>
</p:columnGroup>
</p:dataTable>
</div>
</h:form>
package org.primefaces.showcase.view.data.datatable;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.io.Serializable;
import java.util.List;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.primefaces.event.ColumnResizeEvent;
import org.primefaces.showcase.domain.Product;
import org.primefaces.showcase.service.ProductService;
@Named("dtResizableColumnsView")
@RequestScoped
@RegisterForReflection(serialization = true)
public class ResizableColumnsView implements Serializable {
@Inject
ProductService service;
private List<Product> products1;
private List<Product> products2;
@PostConstruct
public void init() {
products1 = service.getProducts(10);
products2 = service.getProducts(10);
}
public void onResize(ColumnResizeEvent event) {
FacesMessage msg = new FacesMessage("Column " + event.getColumn().getClientId() + " resized", "W:" + event.getWidth() + ", H:" + event.getHeight());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public List<Product> getProducts1() {
return products1;
}
public List<Product> getProducts2() {
return products2;
}
public void setService(ProductService service) {
this.service = service;
}
}
package org.primefaces.showcase.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
import org.primefaces.showcase.domain.InventoryStatus;
import org.primefaces.showcase.domain.Product;
@Named
@ApplicationScoped
public class ProductService {
private List<Product> products;
@PostConstruct
public void init() {
products = new ArrayList<>();
products.add(new Product(1000, "f230fh0g3", "Bamboo Watch", "Product Description", "bamboo-watch.jpg", 65,
"Accessories", 24, InventoryStatus.INSTOCK, 5));
products.add(new Product(1001, "nvklal433", "Black Watch", "Product Description", "black-watch.jpg", 72,
"Accessories", 61, InventoryStatus.INSTOCK, 4));
products.add(new Product(1002, "zz21cz3c1", "Blue Band", "Product Description", "blue-band.jpg", 79,
"Fitness", 2, InventoryStatus.LOWSTOCK, 3));
products.add(new Product(1003, "244wgerg2", "Blue T-Shirt", "Product Description", "blue-t-shirt.jpg", 29,
"Clothing", 25, InventoryStatus.INSTOCK, 5));
products.add(new Product(1004, "h456wer53", "Bracelet", "Product Description", "bracelet.jpg", 15,
"Accessories", 73, InventoryStatus.INSTOCK, 4));
products.add(new Product(1005, "av2231fwg", "Brown Purse", "Product Description", "brown-purse.jpg", 120,
"Accessories", 0, InventoryStatus.OUTOFSTOCK, 4));
products.add(new Product(1006, "bib36pfvm", "Chakra Bracelet", "Product Description", "chakra-bracelet.jpg", 32,
"Accessories", 5, InventoryStatus.LOWSTOCK, 3));
products.add(new Product(1007, "mbvjkgip5", "Galaxy Earrings", "Product Description", "galaxy-earrings.jpg", 34,
"Accessories", 23, InventoryStatus.INSTOCK, 5));
products.add(new Product(1008, "vbb124btr", "Game Controller", "Product Description", "game-controller.jpg", 99,
"Electronics", 2, InventoryStatus.LOWSTOCK, 4));
products.add(new Product(1009, "cm230f032", "Gaming Set", "Product Description", "gaming-set.jpg", 299,
"Electronics", 63, InventoryStatus.INSTOCK, 3));
products.add(new Product(1010, "plb34234v", "Gold Phone Case", "Product Description", "gold-phone-case.jpg", 24,
"Accessories", 0, InventoryStatus.OUTOFSTOCK, 4));
products.add(new Product(1011, "4920nnc2d", "Green Earbuds", "Product Description", "green-earbuds.jpg", 89,
"Electronics", 23, InventoryStatus.INSTOCK, 4));
products.add(new Product(1012, "250vm23cc", "Green T-Shirt", "Product Description", "green-t-shirt.jpg", 49,
"Clothing", 74, InventoryStatus.INSTOCK, 5));
products.add(new Product(1013, "fldsmn31b", "Grey T-Shirt", "Product Description", "grey-t-shirt.jpg", 48,
"Clothing", 0, InventoryStatus.OUTOFSTOCK, 3));
products.add(new Product(1014, "waas1x2as", "Headphones", "Product Description", "headphones.jpg", 175,
"Electronics", 8, InventoryStatus.LOWSTOCK, 5));
products.add(new Product(1015, "vb34btbg5", "Light Green T-Shirt", "Product Description", "light-green-t-shirt.jpg", 49,
"Clothing", 34, InventoryStatus.INSTOCK, 4));
products.add(new Product(1016, "k8l6j58jl", "Lime Band", "Product Description", "lime-band.jpg", 79,
"Fitness", 12, InventoryStatus.INSTOCK, 3));
products.add(new Product(1017, "v435nn85n", "Mini Speakers", "Product Description", "mini-speakers.jpg", 85,
"Clothing", 42, InventoryStatus.INSTOCK, 4));
products.add(new Product(1018, "09zx9c0zc", "Painted Phone Case", "Product Description", "painted-phone-case.jpg", 56,
"Accessories", 41, InventoryStatus.INSTOCK, 5));
products.add(new Product(1019, "mnb5mb2m5", "Pink Band", "Product Description", "pink-band.jpg", 79,
"Fitness", 63, InventoryStatus.INSTOCK, 4));
products.add(new Product(1020, "r23fwf2w3", "Pink Purse", "Product Description", "pink-purse.jpg", 110,
"Accessories", 0, InventoryStatus.OUTOFSTOCK, 4));
products.add(new Product(1021, "pxpzczo23", "Purple Band", "Product Description", "purple-band.jpg", 79,
"Fitness", 6, InventoryStatus.LOWSTOCK, 3));
products.add(new Product(1022, "2c42cb5cb", "Purple Gemstone Necklace", "Product Description", "purple-gemstone-necklace.jpg", 45,
"Accessories", 62, InventoryStatus.INSTOCK, 4));
products.add(new Product(1023, "5k43kkk23", "Purple T-Shirt", "Product Description", "purple-t-shirt.jpg", 49,
"Clothing", 2, InventoryStatus.LOWSTOCK, 5));
products.add(new Product(1024, "lm2tny2k4", "Shoes", "Product Description", "shoes.jpg", 64,
"Clothing", 0, InventoryStatus.INSTOCK, 4));
products.add(new Product(1025, "nbm5mv45n", "Sneakers", "Product Description", "sneakers.jpg", 78,
"Clothing", 52, InventoryStatus.INSTOCK, 4));
products.add(new Product(1026, "zx23zc42c", "Teal T-Shirt", "Product Description", "teal-t-shirt.jpg", 49,
"Clothing", 3, InventoryStatus.LOWSTOCK, 3));
products.add(new Product(1027, "acvx872gc", "Yellow Earbuds", "Product Description", "yellow-earbuds.jpg", 89,
"Electronics", 35, InventoryStatus.INSTOCK, 3));
products.add(new Product(1028, "tx125ck42", "Yoga Mat", "Product Description", "yoga-mat.jpg", 20,
"Fitness", 15, InventoryStatus.INSTOCK, 5));
products.add(new Product(1029, "gwuby345v", "Yoga Set", "Product Description", "yoga-set.jpg", 20,
"Fitness", 25, InventoryStatus.INSTOCK, 8));
}
public List<Product> getProducts() {
return new ArrayList<>(products);
}
public List<Product> getProducts(int size) {
if (size > products.size()) {
Random rand = new Random();
List<Product> randomList = new ArrayList<>();
for (int i = 0; i < size; i++) {
int randomIndex = rand.nextInt(products.size());
randomList.add(products.get(randomIndex));
}
return randomList;
}
else {
return new ArrayList<>(products.subList(0, size));
}
}
public List<Product> getClonedProducts(int size) {
List<Product> results = new ArrayList<>();
List<Product> originals = getProducts(size);
for (Product original : originals) {
results.add(original.clone());
}
// make sure to have unique codes
for (Product product : results) {
product.setCode(UUID.randomUUID().toString().replace("-", "").substring(0, 8));
}
return results;
}
}
package org.primefaces.showcase.domain;
import java.io.Serializable;
import java.util.List;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class Product implements Serializable {
private int id;
private String code;
private String name;
private String description;
private String image;
private double price;
private String category;
private int quantity;
private InventoryStatus inventoryStatus;
private int rating;
private List<Order> orders;
public Product() {
}
public Product(int id, String code, String name, String description, String image, double price, String category, int quantity,
InventoryStatus inventoryStatus, int rating) {
this.id = id;
this.code = code;
this.name = name;
this.description = description;
this.image = image;
this.price = price;
this.category = category;
this.quantity = quantity;
this.inventoryStatus = inventoryStatus;
this.rating = rating;
}
@Override
public Product clone() {
return new Product(getId(), getCode(), getName(), getDescription(), getImage(), getPrice(), getCategory(), getQuantity(),
getInventoryStatus(), getRating());
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public InventoryStatus getInventoryStatus() {
return inventoryStatus;
}
public void setInventoryStatus(InventoryStatus inventoryStatus) {
this.inventoryStatus = inventoryStatus;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public List<Order> getOrders() {
return this.orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Product other = (Product) obj;
if (code == null) {
return other.code == null;
} else {
return code.equals(other.code);
}
}
}
package org.primefaces.showcase.domain;
import java.util.Locale;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public enum InventoryStatus {
INSTOCK("In Stock"),
OUTOFSTOCK("Out of Stock"),
LOWSTOCK("Low Stock");
private final String text;
InventoryStatus(String text) {
this.text = text;
}
public String getText() {
return text;
}
public String getStatusName() {
return name().toLowerCase(Locale.ROOT);
}
}
package org.primefaces.showcase.domain;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class Order implements java.io.Serializable {
private final int number;
private final String imagePath;
public Order(int number, String imagePath) {
this.number = number;
this.imagePath = imagePath;
}
public int getNumber() {
return number;
}
public String getImagePath() {
return imagePath;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Order order = (Order) o;
return number == order.number;
}
@Override
public int hashCode() {
return number;
}
}
package org.primefaces.showcase.view.data.datatable;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.primefaces.showcase.domain.Player;
import org.primefaces.showcase.domain.Sale;
@Named("dtGroupView")
@ViewScoped
@RegisterForReflection(serialization = true)
public class GroupView implements Serializable {
private static final String[] MANUFACTORS;
private static final String[] PLAYER_NAMES;
static {
MANUFACTORS = new String[10];
MANUFACTORS[0] = "Bamboo Watch";
MANUFACTORS[1] = "Black Watch";
MANUFACTORS[2] = "Blue Band";
MANUFACTORS[3] = "Blue T-Shirt";
MANUFACTORS[4] = "Brown Purse";
MANUFACTORS[5] = "Chakra Bracelet";
MANUFACTORS[6] = "Galaxy Earrings";
MANUFACTORS[7] = "Game Controller";
MANUFACTORS[8] = "Gaming Set";
MANUFACTORS[9] = "Gold Phone Case";
PLAYER_NAMES = new String[10];
PLAYER_NAMES[0] = "Lionel Messi";
PLAYER_NAMES[1] = "Cristiano Ronaldo";
PLAYER_NAMES[2] = "Arjen Robben";
PLAYER_NAMES[3] = "Franck Ribery";
PLAYER_NAMES[4] = "Ronaldinho";
PLAYER_NAMES[5] = "Luis Suarez";
PLAYER_NAMES[6] = "Sergio Aguero";
PLAYER_NAMES[7] = "Zlatan Ibrahimovic";
PLAYER_NAMES[8] = "Neymar Jr";
PLAYER_NAMES[9] = "Andres Iniesta";
}
private List<Sale> sales;
private Integer lastYearTotal;
private Integer thisYearTotal;
private List<Integer> years;
private List<Player> players;
@PostConstruct
public void init() {
sales = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sales.add(new Sale(MANUFACTORS[i], getRandomAmount(), getRandomAmount(), getRandomPercentage(), getRandomPercentage()));
}
years = new ArrayList<>();
years.add(2010);
years.add(2011);
years.add(2012);
years.add(2013);
years.add(2014);
players = new ArrayList<>();
for (int i = 0; i < 10; i++) {
players.add(new Player(PLAYER_NAMES[i], generateRandomGoalStatsData()));
}
}
public List<Sale> getSales() {
return sales;
}
private int getRandomAmount() {
return (int) (Math.random() * 100000);
}
private int getRandomPercentage() {
return (int) (Math.random() * 100);
}
public Integer getLastYearTotal() {
if (lastYearTotal == null) {
lastYearTotal = sales.stream().mapToInt(Sale::getLastYearSale).sum();
}
return lastYearTotal;
}
public Integer getThisYearTotal() {
if (thisYearTotal == null) {
thisYearTotal = sales.stream().mapToInt(Sale::getThisYearSale).sum();
}
return thisYearTotal;
}
public List<Integer> getYears() {
return years;
}
public int getYearCount() {
return years.size();
}
public List<Player> getPlayers() {
return players;
}
private Map<Integer, Integer> generateRandomGoalStatsData() {
Map<Integer, Integer> stats = new LinkedHashMap<>();
for (int i = 0; i < 5; i++) {
stats.put(years.get(i), getRandomGoals());
}
return stats;
}
private int getRandomGoals() {
return (int) (Math.random() * 50);
}
}
package org.primefaces.showcase.domain;
import java.io.Serializable;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class Sale implements Serializable {
private String manufacturer;
private int lastYearSale;
private int thisYearSale;
private int lastYearProfit;
private int thisYearProfit;
public Sale() {
}
public Sale(String manufacturer, int lastYearSale, int thisYearSale, int lastYearProfit, int thisYearProfit) {
this.manufacturer = manufacturer;
this.lastYearSale = lastYearSale;
this.thisYearSale = thisYearSale;
this.lastYearProfit = lastYearProfit;
this.thisYearProfit = thisYearProfit;
}
public int getLastYearProfit() {
return lastYearProfit;
}
public void setLastYearProfit(int lastYearProfit) {
this.lastYearProfit = lastYearProfit;
}
public int getLastYearSale() {
return lastYearSale;
}
public void setLastYearSale(int lastYearSale) {
this.lastYearSale = lastYearSale;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public int getThisYearProfit() {
return thisYearProfit;
}
public void setThisYearProfit(int thisYearProfit) {
this.thisYearProfit = thisYearProfit;
}
public int getThisYearSale() {
return thisYearSale;
}
public void setThisYearSale(int thisYearSale) {
this.thisYearSale = thisYearSale;
}
}
package org.primefaces.showcase.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class Player {
private String name;
private final Map<Integer, Integer> goals;
public Player() {
goals = new LinkedHashMap<>();
}
public Player(String name, Map<Integer, Integer> goals) {
this.name = name;
this.goals = goals;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGoals(int year) {
return goals.get(year);
}
}