unable to set true false value to a boolean variable [duplicate] - jsf

This question already has answers here:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
(5 answers)
Closed 3 years ago.
I'm unable to set true false value to a boolean variable
I have the following code
Form.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml">
<h:form>
<p:panel id="work" styleClass="panelNoBorder">
<p:fieldset toggleable="true" toggleSpeed="500" legend="Core">
<h:panelGrid columns="2" styleClass="panelNoBorder"
rendered="#{javaMB.formNotComplete and !javaMB.formRejected}">
<p:outputLabel value="Form Number"/>
<p:row>
<p:inputText id="formNumber" value="#{javaMB.formNumber}" maxlength="10">
</p:inputText>
</p:row>
<p:outputLabel value="Result"/>
<p:row>
<p:inputText id="result" maxlength="10"
value="#{javaMB.result}">
</p:inputText>
</p:row>
</h:panelGrid>
</p:fieldset>
</p:panel>
</h:form>
</ui:composition>
public class JavaMB {
private boolean formRejected = false;
private boolean formNotComplete = true;
public boolean isFormRejected() {
return formRejected;
}
public void setFormRejected(boolean formRejected) {
this.formRejected = formRejected;
}
public boolean isFormNotComplete() {
return formNotComplete;
}
public void setFormNotComplete(boolean formNotComplete) {
this.formNotComplete = formNotComplete;
}
public void initializeWorkFlow() {
logger.debug("Form: " + FormEntity.getFormId());
if (workflow.getActionType().getActionTypeId() == '5') {
this.setFormNotComplete(false);
} else if (workflow.getActionType().getActionTypeId() == '7') {
this.setFormRejected(true);
} else {
}
}
}
The set values are placed inside an if statement , The if Statements work perfectly fine
The problem is that I can't display correctly boolean value. There are NO errors in the console,
this.setFormNotComplete(false);
this.setFormRejected(true);
Any ideas how to solve this issue?
the database has the values for Approved and Not approved, So if the record has a 5 or 7 It must hit those values and not display the panel
In database we have a table workflow and the action type IDs
The action type Ids being set to record has a 5 being approved or 7 being Rejected
Upon these values the setFormNotComplete(false 7 if setFormRejected(true must act
<h:panelGrid
rendered="#{javaMB.formNotComplete and !javaMB.formRejected}">
if (workflow.getActionType().getActionTypeId() == '5') {
this.setFormNotComplete(false);
} else if (workflow.getActionType().getActionTypeId() == '7') {
this.setFormRejected(true);
} else {

For boolean fields the getter method name should be is<First letter capitalised field name> but yours is not.
public boolean isformRejected() should be public boolean isFormRejected() and public boolean isformNotComplete() should be public boolean isFormNotComplete()
So your class should be as follows.
public class JavaMB {
private boolean formRejected = false;
private boolean formNotComplete = true;
public boolean isFormRejected() {
return formRejected;
}
public void setFormRejected(boolean formRejected) {
this.formRejected = formRejected;
}
public boolean isFormNotComplete() {
return formNotComplete;
}
public void setFormNotComplete(boolean formNotComplete) {
this.formNotComplete = formNotComplete;
}
public void initializeWorkFlow() {
logger.debug("Form: " + FormEntity.getFormId());
if (workflow.getActionType().getActionTypeId() == '5') {
this.setFormNotComplete(false);
} else if (workflow.getActionType().getActionTypeId() == '7') {
this.setFormRejected(true);
} else {
}
}
}

Related

Columns (table body) not visible in datatable when using lazydatamodel

Using LazyDataModel does not display columns in the datatable.
I have implemented custom LazyDataModel and I have implemented load method init. However, when I pass the datamodel as a value to the datatable, the columns are not rendered/displayed. But when I pass it as a list, the columns are rendered/displayed.
My LazyDataModel class
public class SearchPmrLazyDataModel extends LazyBaseDataModel<SearchDTO> {
public SearchPmrLazyDataModel() {
}
public void setData() {
if (searchCriteria == null) {
searchCriteria = new PmrSearchCriteriaDTO();
}
setWrappedData(pmrService.searchPmr(searchCriteria, teamId));
}
#Override
public List<PmrSearchResultViewDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
setData();
searchCriteria.setPageRequest(determinePage(first, pageSize));
List<PmrSearchResultViewDTO> data = this.cachedData;
// rowCount
int dataSize = data.size();
this.setRowCount(dataSize);
// paginate
if (dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
} catch (IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
} else {
return data;
}
}
#Override
public void setRowIndex(int rowIndex) {
if (rowIndex == -1 || getPageSize() == 0) {
super.setRowIndex(-1);
}
else
super.setRowIndex(rowIndex % getPageSize());
}
#Override
public Object getRowKey(PmrSearchResultViewDTO obj) {
return obj.getId();
}
}
My bean
public LazyDataModel<SearchDTO> getCorresLazyDataModel(String selectedTabName, String selectedStateName, String selectedStateName2) {
//returns corresponding lazy data model according to a business logic
return getLazyDataModel(selectedTabName, selectedStateName, selectedStateName2);
}
My XHTML page
<p:dataTable
value="#{formBean.getCorresLazyDataModel(pmrStatusTab, pmrState, pmrState2)}"
var="pmr" id="pmrStatusResultTable#{pmrStatusTab}#{pmrState}"
widgetVar="pmrStatusResultTable#{pmrStatusTab}#{pmrState}"
style="overflow: auto; width: auto! important; table-width:fixed"
rows="10" rowKey="#{pmr.id}" rowStyleClass="odd, even"
reflow="true" scrollWidth="#{formBean.scrollWidth}"
scrollable="true" scrollRows="10" paginator="true" lazy="true"
selectionMode="single" selection="#{formBean.selectedPmr}">
<p:ajax event="rowSelect" process="#this"
listener="#{formBean.onRowSelect}" />
<p:columns value="#{formBean.columns}" var="column"
columnIndexVar="colIndex" sortBy="#{pmr[column.property]}"
sortable="true">
<f:facet name="header">
<h:outputText value="#{column.header}" />
</f:facet>
<h:outputText value="#{pmr[column.property]}" />
</p:columns>
</p:dataTable>
The columns are not rendered/displayed only if I pass datamodel directly. If I pass the value as list, they are displayed, is there anything which I am missing?

Using P:CommandButton in PrimeFaces

Originally I have this form for user input and do a search.
<h:form id="wordForm">
<h:panelGrid columns="4">
<h:inputText id="word" "
value="#{wordController.word}" />
<h:message for="word" />
<h:commandButton id="search" value="search"
action="#{wordController.search}" />
</h:panelGrid>
</h:form>
Now I want to use PrimeFaces for autocomplete feature, and this is my new form with Autocomplete. How can I replace the new form with the above form?
<h:form>
<p:growl id="msgs" showDetail="true" />
<h:panelGrid columns="2" cellpadding="5">
<p:autoComplete id="wordForm" value="#{autoCompleteView.query}"
completeMethod="#{autoCompleteView.completeQuery}" var="query"
itemLabel="#{query.displayName}" itemValue="#{query}"
converter="queryConverter" forceSelection="true" />
<p:commandButton value="search" oncomplete="PF('dlg').show()" **action="#{wordController.search}"** />
</h:panelGrid>
</h:form>
More specifically, I think I still need to somehow use "action="#{wordController.search}" in P:CommandAction button so that I don't need to change anything else in backend. But How do I pass the query parameter to the "wordController.word" variable? Because now "action="#autoCompleteView.query" takes the user input.
How can I modify this without significant change to current bean code? Do I have to unify the original search bean WordController with the new AutocompleteView bean? because now the user input is accepted into AutoCompleteView bean.
AutoCompleteView.java
#ManagedBean
public class AutoCompleteView {
private Query query;
#ManagedProperty("#{queryService}")
private QueryService service;
private List<Query> selectedQueries;
public List<Query> completeQuery(String query) {
System.out.println(query);
List<Query> allQueries = service.getQueries();
List<Query> filteredQueries = new ArrayList<Query>();
for (int i = 0; i < allQueries.size(); i++) {
Query skin = allQueries.get(i);
if(skin.getName().toLowerCase().contains(query)) {
filteredQueries.add(skin);
}
}
return filteredQueries;
}
public void onItemSelect(SelectEvent event) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Item Selected", event.getObject().toString()));
}
public Query getQuery() {
return query;
}
public void setQuery(Query query) {
this.query = query;
}
public void setService(QueryService service) {
this.service = service;
}
public List<Query> getSelectedQueries() {
return selectedQueries;
}
public void setSelectedQueries(List<Query> selectedQueries) {
this.selectedQueries = selectedQueries;
}
}
Edited per suggestion:
#Named
#RequestScoped
public class WordController {
private String word;
// For AutoComplete suggestions
private Query selectedQuery;
#Inject
private QueryService service;
#Inject
private Word wordObject;
public void search() {
if (word != null && !word.isEmpty()) {
wordObject.searchWord(word);;
...
}else {
System.out.println("Query can't be null!");
}
}
public List<Query> completeQuery(String query) {
List<Query> allQueries = service.getQueries();
List<Query> filteredQueries = new ArrayList<Query>();
for (int i = 0; i < allQueries.size(); i++) {
Query skin = allQueries.get(i);
if(skin.getName().toLowerCase().contains(query)) {
filteredQueries.add(skin);
}
}
return filteredQueries;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public Query getSelectedQuery() {
return selectedQuery;
}
public void setSelectedQuery(Query selectedQuery) {
this.selectedQuery = selectedQuery;
}
}
Question: Originally, my 'word' is filled through an "h:inputText" in JSF view and search() is called in JSF:
<h:commandButton id="search" value="Search!" action="#{wordController.search}" />
Now, how do I get "selectedQuery" from completeQuery() method, and then use it to fill "word" and then call search() method?

Rendered doesn't work in dataTable primefaces JSF

I have problem with 4 ifs in my code on jsf. I have to check 3 parameteres and when it is ok show appropriate message. Why its doesn't work? In dataGrid it works in c:when
<h:outputLabel value="#{msg.deleted}" class="delete" rendered="#{((!advertisement.isStarted) and (!advertisement.isActive) and (!advertisement.isFinished))}"/>
<h:outputLabel value="#{msg.done}" class="done" rendered="#{((advertisement.isStarted) and (!advertisement.isActive) and (advertisementisFinished))}"/>
<h:outputLabel value="#{msg.realize}" class="realize" rendered="#{((advertisement.isStarted) and (advertisement.isActive) and (!advertisement.isFinished))}"/>
<h:outputLabel value="#{msg.open}" rendered="#{((!advertisement.isStarted) and (advertisement.isActive) and (!advertisement.isFinished))}"/>
All time I dont understand solution of BalusC
I have:
public boolean isIsActive() {
return isActive;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
public boolean isIsStarted() {
return isStarted;
}
public void setIsStarted(boolean isStarted) {
this.isStarted = isStarted;
}
public boolean isIsFinished() {
return isFinished;
}
public void setIsFinished(boolean isFinished) {
this.isFinished = isFinished;
}

Unable to find matching navigation case with from-view-id '/index.xhtml' for action : JSF

I am getting the following error :
Unable to find matching navigation case with from-view-id '/index.xhtml' for action '#{medcontroller.getMedGeneric}' with outcome 'javax.faces.model.ListDataModel#7a652236'
I am new to jsf and I'm really clueless about solving this error. I have a ManagedBean with the following code:
MedController.java
#ManagedBean(name = "medcontroller")
#SessionScoped
public class MedController implements Serializable {
int startId;
String gName;
int endId;
DataModel medNames;
//DataModel medGeneric;
MedicineHelper helper;
private int recordCount = 1000;
private int pageSize = 10;
private Medicine current;
private int selectedItemIndex;
public MedController() {
helper = new MedicineHelper();
startId = 1;
endId = 10;
}
public MedController(int startId, int endId) {
helper = new MedicineHelper();
this.startId = startId;
this.endId = endId;
}
public Medicine getSelected() {
if (current == null) {
current = new Medicine();
selectedItemIndex = -1;
}
return current;
}
public DataModel getMedNames() {
if (medNames == null) {
medNames = new ListDataModel(helper.getMedNames(startId, endId));
}
return medNames;
}
public String getgName()
{
return gName;
}
public void setgName(String gName)
{
this.gName = gName;
}
public DataModel getMedGeneric() {
if (medNames == null) {
medNames= new ListDataModel(helper.getMedGeneric(gName));
}
return medNames;
}
void recreateModel() {
medNames = null;
}
public boolean isHasNextPage() {
if (endId + pageSize <= recordCount) {
return true;
}
return false;
}
public boolean isHasPreviousPage() {
if (startId-pageSize > 0) {
return true;
}
return false;
}
public String next() {
startId = endId+1;
endId = endId + pageSize;
recreateModel();
return "index";
}
public String previous() {
startId = startId - pageSize;
endId = endId - pageSize;
recreateModel();
return "index";
}
public int getPageSize() {
return pageSize;
}
public String prepareView(){
current = (Medicine) getMedNames().getRowData();
return "browse";
}
public String prepareList(){
recreateModel();
return "index";
}
}
And here is my JSF file
index.xhtml
<ui:define name="body">
<h:form styleClass="jsfcrud_list_form">
<h:commandLink action="#{medcontroller.previous}" value="Previous #{medcontroller.pageSize}" rendered="#{medcontroller.hasPreviousPage}"/>
<h:commandLink action="#{medcontroller.next}" value="Next #{medcontroller.pageSize}" rendered="#{medcontroller.hasNextPage}"/>
<h:dataTable value="#{medcontroller.medNames}" var="item" border="1" cellpadding="15" cellspacing="10" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="BrandName"/>
</f:facet>
<h:outputText value="#{item.brandName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Generic"/>
</f:facet>
<h:outputText value="#{item.generic}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{medcontroller.prepareView}" value="View"/>
</h:column>
</h:dataTable>
<h:inputText value="#{medcontroller.gName}" />
<h:commandButton value="Submit" action="#{medcontroller.getMedGeneric}" />
</h:form>
</ui:define>
Please help me solve the error.
Also, I do not have a faces-config.xml file. I am using netbeans ide 7.1.2 web application with jsf and hibernate framework.
Thank you in advance.
The <h:commandButton action> must point to a method which invokes some business logic and returns either void or a String representing the target page you'd like to (re)display. However you returned a whole ListDataModel which isn't making any sense to JSF navigation handler and hence this error.
Something like this should do:
public String getMedGeneric(){
// Do your business logic here.
return "someViewId";
}
This will navigate to someViewId.xhtml. However, if you intend to stick on the same view, just let it return void (or null) and it will redisplay the same view.
public void getMedGeneric(){
// Do your business logic here.
}
By the way, it's really a poor naming convention to prefix action method names with get. This is confusing and makes your code not self-documenting. Rather name it loadMedGeneric() or so. I'm merely guessing as you didn't tell anywhere about the concrete functional requirement, what exactly that button should be doing.
getMedGeneric should return java.lang.String which represent navigation to another page described in faces-config.xml. In your case it return some model so it will not work unfortunatell. Let try to put getMedGeneric() action to actionListener and then in action put navigation String. i.e:
action="navString" actionListener="#{medcontroller.getMedGeneric}"
you should try just
actionListener="#{medcontroller.getMedGeneric}"

Invoke ActionListener of Backing Component in Composite Component

try to write a composite component that allows mutltiple text inputs. I read that it is possible to define a backing component for a composite component, so I don't have to write a renderer nor a handler. What I couldn't figure out is how to delegate actions declared in composite's xhtml to the backing component. I guess i did not yet quite understand the concept of this. Does anybody has an Idea?
I am using Tomcat 7, EL 2.2, Spring 3, Mojarra 2.1.7
This is the way i'd like to use the component:
<custom:multiInput value="#{backingBean.inputList}"/>
Where the BackingBean.java holds a list of objects:
#Component
#Scope(value="view")
public class BackingBean {
...
private List<Foo> inputList;
....
}
The composite component multiInput.xhtml looks like this:
<cc:interface componentType="MultiInput">
<cc:attribute name="value" required="true" type="java.util.List" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:dataTable value="#{cc.attrs.rows}" var="row">
<h:column>
<!-- here will be a selector component in order to select a foo object -->
</h:column>
<h:column>
<h:commandButton value="Remove Row">
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.removeRow(row)}" />
</h:commandButton>
</h:column>
<h:column>
<h:commandButton value="Add Row" rendered="#{cc.lastRow}">
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.addEmptyRow()}" />
</h:commandButton>
</h:column>
</h:dataTable>
</div>
</cc:implementation>
And here the backing component MultiInput.java:
#FacesComponent(value="MultiInput")
public class MultiInput extends UIInput implements NamingContainer, Serializable{
...
#Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
#Override
public void encodeBegin(FacesContext context) throws IOException {
initRowsFromValueAttribute();
super.encodeBegin(context);
}
public void removeRow(MultiInputRow row) {
// why is this method is never reached when clicking remove button?
}
public void addEmptyRow() {
// why is this method is never reached when clicking add button?
}
public ListDataModel<MultiSelectRow> getRows() {
return (ListDataModel<MultiSelectRow>) getStateHelper().eval(PropertyKeys.rows, null);
}
private void setRows(ListDataModel<MultiSelectRow> rows) {
getStateHelper().put(PropertyKeys.rows, rows);
}
...
}
Now - removeRow and addEmptyRow is never called on MultiInput. An ajax request is triggered but it gets lost somewhere. Why?
I think the method signature for ajax listener methods should include the AjaxBehaviorEvent (unverified):
public void addEmptyRow(AjaxBehaviorEvent event) { ... }
and the f:ajax tag should just look like (without parentheses):
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.addEmptyRow}" />
I'm struggling with the same problem here: using <f:ajax>, action listener methods in the composite component backing component are not executed.
It works partially when using Primefaces <p:commandButton>: the action listener method is correctly called in this case. However, the value of the 'process' attribute seems to be ignored in this case: All form fields are submitted, which causes validation failure in my case. If this is not a problem for you, you could try this.
I have created some test classes that reproduce the problem:
The composite component file testComponent.xhtml:
<html xmlns="http://www.w3c.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="testComponent">
</composite:interface>
<composite:implementation>
<div id="#{cc.clientId}">
<h:panelGroup id="addPanel">
<h:inputText id="operand1" value="#{cc.operand1}"/>
<h:outputText value=" + " />
<h:inputText id="operand2" value="#{cc.operand2}"/>
<h:outputText value=" = " />
<h:outputText id="result" value="#{cc.result}" />
<br />
<p:commandButton id="testButton1" value="Primefaces CommandButton"
actionListener="#{cc.add()}" process="addPanel" update="addPanel"/>
<h:commandButton id="testButton2" value="f:ajax CommandButton">
<f:ajax execute="addPanel" render="addPanel" listener="#{cc.add()}" />
</h:commandButton>
</h:panelGroup>
</div>
</composite:implementation>
</html>
The backing component class:
package be.solidfrog.pngwin;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.event.ActionEvent;
#FacesComponent("testComponent")
public class TestComponent extends UINamingContainer {
private Integer operand1, operand2, result;
public void add() {
System.err.println("Adding " + operand1 + " and " + operand2);
result = operand1 + operand2;
}
public Integer getOperand1() { return operand1; }
public void setOperand1(Integer operand1) { this.operand1 = operand1; }
public Integer getOperand2() { return operand2; }
public void setOperand2(Integer operand2) { this.operand2 = operand2; }
public Integer getResult() { return result; }
public void setResult(Integer result) { this.result = result; }
}
And the using page test.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:sf="http://java.sun.com/jsf/composite/solidfrog">
<h:body>
<h:messages />
<h:form id="testForm">
<h:outputLabel for="field1" value="Integer field: "/>
<h:inputText id="field1" value="#{testBean.field1}" />
<hr/>
<sf:testComponent id="testComponent" />
</h:form>
</h:body>
</html>
When clicking the first button and filling in the two operand fields, the result is correctly calculated. However, when a non-numeric value is entered in field1, there is a failed verification.
When using the second button, the action listener method is never calculated. However, the complete form is always submitted, so entering a non-numeric value in field1 triggers the error too.
I also tried p:ajax, which behaved the same as f:ajax.
I really have no idea what is happening here. Hopefully someone with more JSF wisdom can help out.
Although I don't understand everything in detail, I found a way to make it work. Since on each request a new instance of the backing component MultiInput is created, I had to save the state by overwriting saveState and restoreState. This way I could keep the property rows as a simple property. I also removed the encodeBegin method and overwrote getSubmittedValue.
At least this way it is working in Mojarra. When using MyFaces with default settings, I got some serialization exceptions, but I did not get deepter into that since we will stick on Mojarra. Also MyFaces seemed to be more stricked with ajax event listeners. It required "AjaxBehaviorEvent" parameters in listener methods.
Here the complete backing component MultInput:
#FacesComponent(value = "MultiInput")
public class MultiInput extends UIInput implements NamingContainer, Serializable {
ListDataModel<MultiInputRow> rows;
#Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
#Override
public Object getSubmittedValue() {
List<Object> values = new ArrayList<Object>();
List<MultiInputRow> wrappedData = (List<MultiInputRow>) getRows().getWrappedData();
for (MultiInputRow row : wrappedData) {
if (row.getValue() != null) { // only if a valid value was selected
values.add(row.getValue());
}
}
return values;
}
public boolean isLastRow() {
int row = getRows().getRowIndex();
int count = getRows().getRowCount();
return (row + 1) == count;
}
public boolean isFirstRow() {
int row = getRows().getRowIndex();
return 0 == row;
}
public void removeRow(AjaxBehaviorEvent e) {
List<MultiInputRow> wrappedData = (List<MultiInputRow>) getRows().getWrappedData();
wrappedData.remove(rows.getRowIndex());
addRowIfEmptyList();
}
public void addEmptyRow(AjaxBehaviorEvent e) {
List<MultiInputRow> wrappedData = (List<MultiInputRow>) getRows().getWrappedData();
wrappedData.add(new MultiInputRow(null));
}
public ListDataModel<MultiInputRow> getRows() {
if (rows == null) {
rows = createRows();
addRowIfEmptyList();
}
return rows;
}
public List<Object> getValues() {
return (List<Object>) super.getValue();
}
private ListDataModel<MultiInputRow> createRows() {
List<MultiInputRow> wrappedData = new ArrayList<MultiInputRow>();
List<Object> values = getValues();
if (values != null) {
for (Object value : values) {
wrappedData.add(new MultiInputRow(value));
}
}
return new ListDataModel<MultiInputRow>(wrappedData);
}
private void addRowIfEmptyList() {
List<MultiInputRow> wrappedData = (List<MultiInputRow>) rows.getWrappedData();
if (wrappedData.size() == 0) {
wrappedData.add(new MultiInputRow(null));
}
}
#Override
public Object saveState(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
Object[] values = new Object[2];
values[0] = super.saveState(context);
values[1] = rows != null ? rows.getWrappedData() : null;
return (values);
}
#Override
public void restoreState(FacesContext context, Object state) {
if (context == null) {
throw new NullPointerException();
}
if (state == null) {
return;
}
Object[] values = (Object[]) state;
super.restoreState(context, values[0]);
rows = values[1] != null ? new ListDataModel<MultiInputRow>((List<MultiInputRow>) values[1]) : null;
}
/**
* Represents an editable row that holds a value that can be edited.
*/
public class MultiInputRow {
private Object value;
MultiInputRow(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
}

Resources