Layout creates a border layout that has an auto-sizing 'center pane' surrounded by up to four closable and resizable 'border panes' (north, south, east and west). Layouts can be nested, used for an entire page (full page layout) or for a region of the page (element layout), and have client-side and server-side state management.
Setting fullPage="false" creates an element layout. Two element layouts with server-side state management
are shown below: resize, open or close panes and switch between the layouts. Both are described by
LayoutOptions bound to the options attribute; options can also be set as attributes of
pe:layoutPane (the Java model takes precedence).
A full page layout with nested panes, the AJAX events open, close and resize and client-side state
management (stateCookie="true"). The buttons in the north pane call the widget methods
sizePane(), toggle(), close() and open(); nested panes are addressed
with _, e.g. sizePane('center_north', 300). The "center" pane itself can not be manipulated.
Source: fullPage.xhtml below.
The layout is created by options defined as attributes of pe:layoutPane, without a LayoutOptions
model. Default tooltips (resize, open, close, slide) are redefined on pe:layout and per pane. Layout panes
support a limited set of options compared to LayoutOptions. Source: fullPageAttr.xhtml below.
Custom content can be placed between layout panes by putting nested panes in a div with the class
ui-layout-content (shown here, the nested panes come from an included page), by the option
containerSelector of the child options, or in the header facet of a pane, which stays fixed
while the pane content scrolls (shown here with messages). Call the widget method sizeContent(pane) when
custom content changes its height. Source: customContent.xhtml and customContentNested.xhtml below.
An iframe can be a direct child of a layout pane. Set maskContents="true" on the pane to avoid resizing
issues with iframes (maskObjects="true" for objects such as maps), and consider
maskPanesEarly="true" on pe:layout. The style class .ui-layout-mask is made
visible in this example. Source: iframe.xhtml below.
The layout is described by a model which binds all layout options together: the class LayoutOptions.
This way all options of the underlying jQuery layout plugin are available, see the
overview of layout options,
the layout examples site and the
changelog.
Alternatively the mostly used options can be set as tag attributes of pe:layoutPane; no
LayoutOptions is needed then, but the possibilities are limited.
The options attribute points to an instance of LayoutOptions or to a JSON string of serialized
LayoutOptions. LayoutOptions are always serialized to JSON for the widget; when the layout is built once in an
application scoped bean, use toJson() to serialize the options once and pass the string.
<div class="card">
<h5>Element layout and server-side state management</h5>
<p>
Setting <code>fullPage="false"</code> creates an element layout. Two element layouts with server-side state management
are shown below: resize, open or close panes and switch between the layouts. Both are described by
<code>LayoutOptions</code> bound to the <code>options</code> attribute; options can also be set as attributes of
<code>pe:layoutPane</code> (the Java model takes precedence).
</p>
<h:form id="formElementLayout">
<h:panelGroup id="layoutsContainer">
<p:commandButton value="Switch between element layouts" actionListener="#{elementLayoutController.toogleLayout}"
process="layoutsContainer" update="layoutsContainer" icon="pi pi-external-link"/>
<h:panelGrid id="layoutsGrid" columns="2" style="margin-top: 15px;" cellpadding="0" cellspacing="0">
<pe:layout fullPage="false" style="width:450px; height:220px;"
options="#{elementLayoutController.layoutOptionsOne}"
rendered="#{elementLayoutController.layoutOneShown}"
state="#{elementLayoutController.stateOne}">
<pe:layoutPane position="west">
Left
</pe:layoutPane>
<pe:layoutPane position="center">
Center
</pe:layoutPane>
</pe:layout>
<pe:layout fullPage="false" style="width:450px; height:220px;"
options="#{elementLayoutController.layoutOptionsTwo}"
rendered="#{!elementLayoutController.layoutOneShown}"
state="#{elementLayoutController.stateTwo}">
<pe:layoutPane position="east">
<pe:layoutPane position="center">
<f:facet name="header">
Header East-Center
</f:facet>
East-Center
</pe:layoutPane>
<pe:layoutPane position="south">
<f:facet name="header">
Header East-South
</f:facet>
East-South
</pe:layoutPane>
</pe:layoutPane>
<pe:layoutPane position="center">
Center
</pe:layoutPane>
</pe:layout>
</h:panelGrid>
</h:panelGroup>
</h:form>
</div>
<div class="card">
<h5>Full page layout, events and client-side state management</h5>
<p>
A full page layout with nested panes, the AJAX events <i>open</i>, <i>close</i> and <i>resize</i> and client-side state
management (<code>stateCookie="true"</code>). The buttons in the north pane call the widget methods
<code>sizePane()</code>, <code>toggle()</code>, <code>close()</code> and <code>open()</code>; nested panes are addressed
with <code>_</code>, e.g. <code>sizePane('center_north', 300)</code>. The "center" pane itself can not be manipulated.
Source: <i>fullPage.xhtml</i> below.
</p>
<p:linkButton value="Show full page layout" icon="pi pi-external-link" target="_blank"
href="#{request.contextPath}/ui/panel/layout/standalone/fullPage"/>
</div>
<div class="card">
<h5>Layout created by options as tag attributes</h5>
<p>
The layout is created by options defined as attributes of <code>pe:layoutPane</code>, without a <code>LayoutOptions</code>
model. Default tooltips (resize, open, close, slide) are redefined on <code>pe:layout</code> and per pane. Layout panes
support a limited set of options compared to <code>LayoutOptions</code>. Source: <i>fullPageAttr.xhtml</i> below.
</p>
<p:linkButton value="Show layout created by pane options" icon="pi pi-external-link" target="_blank"
href="#{request.contextPath}/ui/panel/layout/standalone/fullPageAttr"/>
</div>
<div class="card">
<h5>Custom content between layout panes</h5>
<p>
Custom content can be placed between layout panes by putting nested panes in a <code>div</code> with the class
<code>ui-layout-content</code> (shown here, the nested panes come from an included page), by the option
<code>containerSelector</code> of the child options, or in the <code>header</code> facet of a pane, which stays fixed
while the pane content scrolls (shown here with messages). Call the widget method <code>sizeContent(pane)</code> when
custom content changes its height. Source: <i>customContent.xhtml</i> and <i>customContentNested.xhtml</i> below.
</p>
<p:linkButton value="Show full page layout with custom content" icon="pi pi-external-link" target="_blank"
href="#{request.contextPath}/ui/panel/layout/standalone/customContent"/>
</div>
<div class="card">
<h5>IFrame acting as layout pane (tips to objects within panes)</h5>
<p>
An iframe can be a direct child of a layout pane. Set <code>maskContents="true"</code> on the pane to avoid resizing
issues with iframes (<code>maskObjects="true"</code> for objects such as maps), and consider
<code>maskPanesEarly="true"</code> on <code>pe:layout</code>. The style class <code>.ui-layout-mask</code> is made
visible in this example. Source: <i>iframe.xhtml</i> below.
</p>
<p:linkButton value="Show full page layout with iframe" icon="pi pi-external-link" target="_blank"
href="#{request.contextPath}/ui/panel/layout/standalone/iframe"/>
</div>
package org.primefaces.extensions.showcase.controller.layout;
import java.io.Serial;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.faces.event.ActionEvent;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import org.primefaces.extensions.model.layout.LayoutOptions;
/**
* LayoutController
*
* @author Oleg Varaksin / last modified by $Author$
* @version $Revision$
*/
@Named
@ViewScoped
public class ElementLayoutController implements Serializable {
@Serial
private static final long serialVersionUID = 20120925L;
private String stateOne;
private String stateTwo;
private boolean layoutOneShown = true;
private LayoutOptions layoutOptionsOne;
private LayoutOptions layoutOptionsTwo;
@PostConstruct
protected void initialize() {
// 1. set options for first layout
layoutOptionsOne = new LayoutOptions();
// options for all panes (center and west)
LayoutOptions panes = new LayoutOptions();
panes.addOption("slidable", false);
panes.addOption("resizeWhileDragging", true);
layoutOptionsOne.setPanesOptions(panes);
// options for west pane
final LayoutOptions west = new LayoutOptions();
west.addOption("size", 150);
west.addOption("minSize", 40);
west.addOption("maxSize", 300);
layoutOptionsOne.setWestOptions(west);
// 2. set options for second layout
layoutOptionsTwo = new LayoutOptions();
// options for all panes
panes = new LayoutOptions();
panes.addOption("slidable", false);
panes.addOption("resizeWhileDragging", true);
layoutOptionsTwo.setPanesOptions(panes);
// options for east pane
final LayoutOptions east = new LayoutOptions();
panes.addOption("resizable", false);
panes.addOption("closable", false);
east.addOption("size", "50%");
layoutOptionsTwo.setEastOptions(east);
// options for nested east layout
final LayoutOptions childEastOptions = new LayoutOptions();
east.setChildOptions(childEastOptions);
// options for east-south pane
final LayoutOptions eastSouth = new LayoutOptions();
eastSouth.addOption("size", "50%");
childEastOptions.setSouthOptions(eastSouth);
}
public String getStateOne() {
return stateOne;
}
public void setStateOne(final String stateOne) {
this.stateOne = stateOne;
}
public String getStateTwo() {
return stateTwo;
}
public void setStateTwo(final String stateTwo) {
this.stateTwo = stateTwo;
}
public void toogleLayout(final ActionEvent event) {
layoutOneShown = !layoutOneShown;
}
public boolean isLayoutOneShown() {
return layoutOneShown;
}
public LayoutOptions getLayoutOptionsOne() {
return layoutOptionsOne;
}
public LayoutOptions getLayoutOptionsTwo() {
return layoutOptionsTwo;
}
}
<p:growl id="growl" showDetail="true" showSummary="true"/>
<h:form id="formFullPage">
<pe:layout id="fullPage" options="#{fullLayoutController.layoutOptions}"
stateCookie="true" widgetVar="fpLayoutWidget">
<p:ajax event="open" listener="#{fullLayoutController.handleOpen}" update="msg"/>
<p:ajax event="close" listener="#{fullLayoutController.handleClose}" update="msg"/>
<p:ajax event="resize" listener="#{fullLayoutController.handleResize}" update=":growl"/>
<pe:layoutPane position="north">
North
<h:panelGrid columns="6" style="margin-left:80px;">
<p:commandButton value="Toggle South" type="button"
onclick="PF('fpLayoutWidget').toggle('south')"/>
<p:commandButton value="Toggle West-North" type="button"
onclick="PF('fpLayoutWidget').toggle('west_north')"/>
<p:commandButton value="Close Center-North" type="button"
onclick="PF('fpLayoutWidget').close('center_north')"/>
<p:commandButton value="Open Center-North" type="button"
onclick="PF('fpLayoutWidget').open('center_north')"/>
<p:commandButton value="Size East Pane" type="button"
onclick="PF('fpLayoutWidget').sizePane('east', 350)"/>
<p:commandButton value="Size West-South Pane" type="button"
onclick="PF('fpLayoutWidget').sizePane('west_south', 80)"/>
</h:panelGrid>
</pe:layoutPane>
<pe:layoutPane position="center">
<pe:layoutPane position="north">
<f:facet name="header">
<h:outputText value="Center-North"/>
</f:facet>
Refresh this page to see that the state of all panes is preserved
</pe:layoutPane>
<pe:layoutPane position="center">
<f:facet name="header">
<h:outputText value="Center-Center"/>
</f:facet>
<p:messages id="msg" showDetail="true" showSummary="true">
<p:effect type="pulsate" event="load" delay="0">
<f:param name="mode" value="'show'"/>
<f:param name="times" value="'1'"/>
</p:effect>
</p:messages>
</pe:layoutPane>
</pe:layoutPane>
<pe:layoutPane position="west">
<pe:layoutPane position="north">
West-North
</pe:layoutPane>
<pe:layoutPane position="center">
West-Center
</pe:layoutPane>
<pe:layoutPane position="south">
West-South
</pe:layoutPane>
</pe:layoutPane>
<pe:layoutPane position="east">
East
</pe:layoutPane>
<pe:layoutPane position="south">
South
</pe:layoutPane>
</pe:layout>
</h:form>
<style>
body {
margin: 4px !important;
}
</style>
package org.primefaces.extensions.showcase.controller.layout;
import java.io.Serial;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import org.primefaces.extensions.component.layout.LayoutPane;
import org.primefaces.extensions.event.CloseEvent;
import org.primefaces.extensions.event.OpenEvent;
import org.primefaces.extensions.event.ResizeEvent;
import org.primefaces.extensions.model.layout.LayoutOptions;
/**
* LayoutController
*
* @author Oleg Varaksin / last modified by $Author$
* @version $Revision$
*/
@Named
@ViewScoped
public class FullLayoutController implements Serializable {
@Serial
private static final long serialVersionUID = 20120925L;
private LayoutOptions layoutOptions;
@PostConstruct
protected void initialize() {
layoutOptions = new LayoutOptions();
// options for all panes
final LayoutOptions panes = new LayoutOptions();
panes.addOption("slidable", false);
panes.addOption("resizeWhileDragging", false);
layoutOptions.setPanesOptions(panes);
// options for center pane
final LayoutOptions center = new LayoutOptions();
layoutOptions.setCenterOptions(center);
// options for nested center layout
final LayoutOptions childCenterOptions = new LayoutOptions();
center.setChildOptions(childCenterOptions);
// options for center-north pane
final LayoutOptions centerNorth = new LayoutOptions();
centerNorth.addOption("size", "50%");
childCenterOptions.setNorthOptions(centerNorth);
// options for center-center pane
final LayoutOptions centerCenter = new LayoutOptions();
centerCenter.addOption("minHeight", 60);
childCenterOptions.setCenterOptions(centerCenter);
// options for west pane
final LayoutOptions west = new LayoutOptions();
west.addOption("size", 200);
layoutOptions.setWestOptions(west);
// options for nested west layout
final LayoutOptions childWestOptions = new LayoutOptions();
west.setChildOptions(childWestOptions);
// options for west-north pane
final LayoutOptions westNorth = new LayoutOptions();
westNorth.addOption("size", "33%");
childWestOptions.setNorthOptions(westNorth);
// options for west-center pane
final LayoutOptions westCenter = new LayoutOptions();
westCenter.addOption("minHeight", "60");
childWestOptions.setCenterOptions(westCenter);
// options for west-south pane
final LayoutOptions westSouth = new LayoutOptions();
westSouth.addOption("size", "33%");
childWestOptions.setSouthOptions(westSouth);
// options for east pane
final LayoutOptions east = new LayoutOptions();
east.addOption("size", 200);
layoutOptions.setEastOptions(east);
// options for south pane
final LayoutOptions south = new LayoutOptions();
south.addOption("size", 80);
layoutOptions.setSouthOptions(south);
}
public LayoutOptions getLayoutOptions() {
return layoutOptions;
}
public void handleClose(final CloseEvent event) {
final FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Layout Pane closed",
"Position:" + ((LayoutPane) event.getComponent()).getPosition());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void handleOpen(final OpenEvent event) {
final FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Layout Pane opened",
"Position:" + ((LayoutPane) event.getComponent()).getPosition());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void handleResize(final ResizeEvent event) {
final FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Layout Pane resized",
"Position:" + ((LayoutPane) event.getComponent()).getPosition() + ", new width = " + event.getWidth()
+ "px, new height = " + event.getHeight() + "px");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
<h:form id="formFullPageAttr">
<pe:layout resizerTip="Resize Default" togglerTipClosed="Close Default" togglerTipOpen="Open Default" sliderTip="Slide Default">
<pe:layoutPane position="north" size="80" closable="false">
North
</pe:layoutPane>
<pe:layoutPane position="center">
<pe:layoutPane position="north" size="50%" resizerTip="Resize North" togglerTipClosed="Close North" togglerTipOpen="Open North" sliderTip="Slide North">
<f:facet name="header">
<h:outputText value="Center-North"/>
</f:facet>
</pe:layoutPane>
<pe:layoutPane position="center" minHeight="60" resizerTip="Resize North" togglerTipClosed="Close North" togglerTipOpen="Open North" sliderTip="Slide North">
<f:facet name="header">
<h:outputText value="Center-Center"/>
</f:facet>
</pe:layoutPane>
</pe:layoutPane>
<pe:layoutPane position="west" size="200">
<pe:layoutPane position="north" size="33%" resizerTip="Resize West" togglerTipClosed="Close West" togglerTipOpen="Open West" sliderTip="Slide West">
West-North
</pe:layoutPane>
<pe:layoutPane position="center" minHeight="60" resizerTip="Resize West" togglerTipClosed="Close West" togglerTipOpen="Open West" sliderTip="Slide West">
West-Center
</pe:layoutPane>
<pe:layoutPane position="south" size="33%" initClosed="true" resizerTip="Resize West" togglerTipClosed="Close West" togglerTipOpen="Open West" sliderTip="Slide West">
West-South
</pe:layoutPane>
</pe:layoutPane>
<pe:layoutPane position="east" size="200" resizeWhileDragging="true">
East
</pe:layoutPane>
<pe:layoutPane position="south" size="80">
South
</pe:layoutPane>
</pe:layout>
</h:form>
<style>
body {
margin: 4px !important;
}
</style>
<h:form id="formCustomContent">
<pe:layout id="fullPage" options="#{customContentLayoutController.layoutOptions}"
widgetVar="fpLayoutWidget">
<pe:layoutPane position="north">
North
</pe:layoutPane>
<pe:layoutPane position="center">
<div style="padding:10px; margin-bottom:6px; border:1px solid red; border-radius: var(--p-content-border-radius);"
class="p-widget-content">
This is a custom content between layout panes.
<br/><br/>
Any elements can be placed here.
</div>
<div class="ui-layout-content">
<!-- nested layout panes: customContentNested.xhtml -->
<ui:include src="#{customContentLayoutController.src}"/>
</div>
</pe:layoutPane>
<pe:layoutPane position="west" styleHeader="background:none; border:none; padding:0;">
<f:facet name="header">
<p:outputPanel id="msgPanel">
<p:autoUpdate/>
<p:messages id="messages" showSummary="true" showDetail="false"/>
<script type="text/javascript">
/* <![CDATA[ */
if (#{facesContext.partialViewContext.ajaxRequest}) {
$(function() {
PF('fpLayoutWidget').sizeContent('west');
});
}
/* ]]> */
</script>
</p:outputPanel>
</f:facet>
Click on the buttons to see that scrollbars in the west pane are well adjusted and messages preserve their place when scrolling.
<h:panelGrid columns="2" style="margin:15px">
<p:commandButton value="Show messages" process="@this" style="margin-right:5px;"
action="#{customContentLayoutController.showMessages}"/>
<p:commandButton value="Hide messages" process="@this"
action="#{customContentLayoutController.hideMessages}"/>
</h:panelGrid>
<p:dataTable id="dataTable" var="message" value="#{dataTableController.messages}" paginator="true"
rows="30" rowsPerPageTemplate="20,30,40">
<p:column sortBy="#{message.subject}" headerText="Subject">
<h:outputText value="#{message.subject}"/>
</p:column>
<p:column sortBy="#{message.text}" headerText="Text">
<h:outputText value="#{message.text}"/>
</p:column>
<p:column sortBy="#{message.subject}" headerText="Subject">
<h:outputText value="#{message.subject}"/>
</p:column>
<p:column sortBy="#{message.text}" headerText="Text">
<h:outputText value="#{message.text}"/>
</p:column>
<p:column sortBy="#{message.subject}" headerText="Subject">
<h:outputText value="#{message.subject}"/>
</p:column>
<p:column sortBy="#{message.text}" headerText="Text">
<h:outputText value="#{message.text}"/>
</p:column>
</p:dataTable>
</pe:layoutPane>
<pe:layoutPane position="south">
South
</pe:layoutPane>
</pe:layout>
</h:form>
<style>
body {
margin: 4px !important;
}
body > form > .ui-layout-north {
background: none;
border: none;
color: var(--p-text-color);
padding: 4px;
overflow: hidden;
}
body > form > .ui-layout-south {
background: none;
border: none;
color: var(--p-text-color);
overflow: hidden;
vertical-align: middle;
}
.p-datatable thead th,
.p-datatable tbody td,
.p-datatable tfoot td {
white-space: nowrap;
}
.p-messages-info,
.p-messages-warn,
.p-messages-error,
.p-messages-fatal {
margin: 0;
}
#formCustomContent\:messages > div {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
</style>
package org.primefaces.extensions.showcase.controller.layout;
import java.io.Serial;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import org.primefaces.extensions.model.layout.LayoutOptions;
/**
* CustomContentLayoutController
*
* @author Oleg Varaksin / last modified by $Author$
* @version $Revision$
*/
@Named
@ViewScoped
public class CustomContentLayoutController implements Serializable {
@Serial
private static final long serialVersionUID = 20120925L;
private final String src = "/ui/panel/layout/standalone/customContentNested.xhtml";
private LayoutOptions layoutOptions;
@PostConstruct
protected void initialize() {
layoutOptions = new LayoutOptions();
// options for all panes
final LayoutOptions panes = new LayoutOptions();
panes.addOption("slidable", false);
layoutOptions.setPanesOptions(panes);
// north pane
final LayoutOptions north = new LayoutOptions();
north.addOption("resizable", false);
north.addOption("closable", false);
north.addOption("size", 60);
north.addOption("spacing_open", 0);
layoutOptions.setNorthOptions(north);
// south pane
final LayoutOptions south = new LayoutOptions();
south.addOption("resizable", false);
south.addOption("closable", false);
south.addOption("size", 28);
south.addOption("spacing_open", 0);
layoutOptions.setSouthOptions(south);
// west pane
final LayoutOptions west = new LayoutOptions();
west.addOption("size", 340);
west.addOption("minSize", 150);
west.addOption("maxSize", 500);
layoutOptions.setWestOptions(west);
final LayoutOptions center = new LayoutOptions();
center.addOption("resizable", false);
center.addOption("closable", false);
center.addOption("minWidth", 200);
center.addOption("minHeight", 60);
layoutOptions.setCenterOptions(center);
// set options for nested center layout
final LayoutOptions optionsNested = new LayoutOptions();
center.setChildOptions(optionsNested);
// options for center-north pane
final LayoutOptions centerNorth = new LayoutOptions();
centerNorth.addOption("size", "50%");
optionsNested.setNorthOptions(centerNorth);
// options for center-center pane
final LayoutOptions centerCenter = new LayoutOptions();
centerCenter.addOption("minHeight", 60);
optionsNested.setCenterOptions(centerCenter);
}
public LayoutOptions getLayoutOptions() {
return layoutOptions;
}
public String getSrc() {
return src;
}
public void showMessages() {
final FacesContext fc = FacesContext.getCurrentInstance();
final FacesMessage msg1 = new FacesMessage(FacesMessage.SEVERITY_ERROR, "This is the first error message",
null);
final FacesMessage msg2 = new FacesMessage(FacesMessage.SEVERITY_ERROR, "This is the second error message",
null);
fc.addMessage(null, msg1);
fc.addMessage(null, msg2);
}
public void hideMessages() {
// nothing to do
}
}
package org.primefaces.extensions.showcase.controller;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
/**
* DataTableController
*
* @author Thomas Andraschko / last modified by $Author$
* @version $Revision$
*/
@Named
@ViewScoped
public class DataTableController implements Serializable {
@Serial
private static final long serialVersionUID = 20111020L;
private List<Message> messages;
private List<Message> filteredMessages;
private String newSubject = "my subject";
private String newText = "my text";
public DataTableController() {
if (messages == null) {
messages = new ArrayList<>();
for (int i = 0; i < 100; i++) {
final Message message = new Message();
message.setSubject("subject " + i);
message.setText("text " + i);
messages.add(message);
}
}
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(final List<Message> messages) {
this.messages = messages;
}
public List<Message> getFilteredMessages() {
return filteredMessages;
}
public void setFilteredMessages(final List<Message> filteredMessages) {
this.filteredMessages = filteredMessages;
}
public String getNewSubject() {
return newSubject;
}
public void setNewSubject(final String newSubject) {
this.newSubject = newSubject;
}
public String getNewText() {
return newText;
}
public void setNewText(final String newText) {
this.newText = newText;
}
public String addMessage() {
doSomething();
final Message message = new Message();
message.setSubject(newSubject);
message.setText(newText);
messages.add(0, message);
newSubject = "";
newText = "";
final FacesContext fc = FacesContext.getCurrentInstance();
fc.addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "New message has been added successfully", null));
return null;
}
public void doSomething() {
try {
// simulate a long running request
Thread.sleep(1500);
}
catch (final Exception e) {
// Restore interrupted state...
Thread.currentThread().interrupt();
}
}
public class Message implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String subject;
private String text;
private long time;
public Message() {
time = System.currentTimeMillis() + (long) (ThreadLocalRandom.current().nextDouble() * 10);
}
public final String getSubject() {
return subject;
}
public final void setSubject(final String subject) {
this.subject = subject;
}
public final String getText() {
return text;
}
public final void setText(final String text) {
this.text = text;
}
public long getTime() {
return time;
}
public void setTime(final long time) {
this.time = time;
}
}
}
<pe:layoutPane position="north">
Center-North
</pe:layoutPane>
<pe:layoutPane position="center">
Center-Center
</pe:layoutPane>
<h:form id="formIframe">
<pe:layout maskPanesEarly="true">
<pe:layoutPane position="north" size="85">
North
</pe:layoutPane>
<pe:layoutPane position="center" maskContents="true">
<iframe id="iframeCenter"
src="https://primefaces-extensions.github.io"
title="PFE Layout"
width="100%"
height="100%">
</iframe>
</pe:layoutPane>
<pe:layoutPane position="west" size="250" resizeWhileDragging="false"
maxSize="500" minSize="100" resizable="true" closable="true">
West
</pe:layoutPane>
</pe:layout>
</h:form>
<style>
body {
margin: 4px !important;
}
/* masks are usually transparent, but we make them visible here */
.ui-layout-mask {
background: #C00 !important;
opacity: .20 !important;
}
</style>