检索 ArrayList 中已更改对象的索引的方法?
Way to retrieving index of changed Object in ArrayList?
我有一个 Web 应用程序,它使用 JSF 中的数据表和 Primefaces 功能,以便它可以执行一些更动态的功能。在数据表中,我有包含可编辑数据的行。我的最终目标是让用户能够编辑该数据,单击保存按钮,然后将执行更新语句以替换数据库中的内容。问题是此时我不知道如何检测 arrayList 中对象的变化。
我做了一个例子,看看有没有人能解决我的困境。听说我有创建数据表的代码,数据表中是来自 ArrayList 的对象,每个对象包含三个不同的字符串。对象在数据表中是可编辑的。我至少需要能够检索在页面上编辑的对象的 ArrayList 索引。有了它,我可以形成一个新的编辑对象列表,并编写一个只对编辑的对象执行批量更新的方法(我的场景中的一个对象相当于数据库中的一行数据)。我以前的方法是遍历整个 ArrayList 并更新所有对象(行),但是,随着列表变大,这样做的成本会变得非常高。现在我有一个 primefaces 方法 onCellEdit,它告诉我一个以前的值和它被更改为的值,但无法查明对象已更改。任何帮助,将不胜感激。下面的代码是这样设置的,可以复制粘贴执行。
编辑:
在我的情况下,我不需要更新 ArrayList。这是使用页面上的输入以及 bean 的 getter 和 setter 自动完成的。我需要做的是知道编辑了哪些 对象(行) 以便我可以将它们拉到一边并执行数据库更新,其中我只更新编辑的内容。 ArrayList 是数据库中内容的镜像,但此处的目标是更新数据库以镜像已编辑的 ArrayList, 而无需 遍历整个 List。
Prod.java
public class Prod{
private String value1;
private String value2;
private String value3;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getValue3() {
return value3;
}
public void setValue3(String value3) {
this.value3 = value3;
}
}
Listen.java
import java.io.IOException;
import java.util.ArrayList;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.primefaces.event.CellEditEvent;
import com.product.inventory.beans.Prod;
@ManagedBean(name = "listen")
@SessionScoped
public class Listen{
private ArrayList<Prod> products;
boolean firstEdit = true;
public Listen(){
}
public ArrayList<Prod> setup(){
ArrayList<Prod> result = new ArrayList<>();
int numObject = 100;
int iterations = 0;
while( iterations < numObject){
Prod prod = new Prod();
prod.setValue1("A" + iterations);
prod.setValue2("B" + iterations);
prod.setValue3("C" + iterations);
result.add(prod);
iterations = iterations + 1;
}
return result;
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
if(isFirstEdit()){
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new
FacesMessage(FacesMessage.SEVERITY_INFO,
"Note", "To confirm changes, please select 'Save Changes'
or they will not be saved.") );
this.setFirstEdit(false);
}
}
public void goTest(){
System.out.println("Initializing...");
this.products = setup();
ExternalContext ec = FacesContext.getCurrentInstance()
.getExternalContext();
try {
ec.redirect(ec.getRequestContextPath()
+ "/test.xhtml");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Table Structure Made");
}
public boolean isFirstEdit() {
return firstEdit;
}
public void setFirstEdit(boolean firstEdit) {
this.firstEdit = firstEdit;
}
public ArrayList<Prod> getProducts() {
return products;
}
public void setProducts(ArrayList<Prod> products) {
this.products = products;
}
}
test.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="form" method="post">
<p:growl id="msgs" showDetail="true" sticky="false">
</p:growl>
<div >
<p:dataTable id="products" var="prod" value="#{listen.products}"
scrollable="true" scrollHeight="900"
editable = "true" editMode="cell" widgetVar= "prodCell">
<p:ajax event="cellEdit" listener="#{listen.onCellEdit}"
update=":form:msgs"/>
<p:column filterBy="#{prod.value1}" filterMatchMode="contains"
style = "width: 300px;" headerText="Name">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#
{prod.value1}" /></f:facet>
<f:facet name="input"><p:inputTextarea rows="2" value="#
{prod.value1}" style = "width: 96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style = "width: 140px;" headerText="Vendor">
<p:cellEditor >
<f:facet name="output"><h:outputText value="#
{prod.value2}" /></f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{prod.value2}"
style="width:100%">
<f:selectItem itemValue="Y" itemLabel="Yes"/>
<f:selectItem itemValue="N" itemLabel="No"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style = "width: 275px;" headerText="Version Release">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#
{prod.value3}" /></f:facet>
<f:facet name="input"><p:inputTextarea rows="1" value="#
{prod.value3}" style = "width: 96%"/></f:facet>
</p:cellEditor>
</p:column>
<f:facet name="footer">
<div align = "left">
<p:commandButton value="post" action="#{tables.showChange}"
ajax="false"></p:commandButton>
</div>
</f:facet>
</p:dataTable>
</div>
<p:contextMenu for="products" widgetVar="pMenu">
<p:menuitem value="Edit Cell" icon="pi pi-search"
onclick="PF('prodCell').showCellEditor();return false;"/>
<p:menuitem value="Hide Menu" icon="pi pi-times"
onclick="PF('pMenu').hide()"/>
</p:contextMenu>
</h:form>
Index.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form method="post">
<h:commandButton value = "Contact Spreadsheet" ajax="false"
action="#{listen.goTest}" ></h:commandButton>
</h:form>
</h:body>
</html>
您想要的解决方案是您正在寻找的行为的 PrimeFaces Extensions Sheet 组件。
Sheet 满足了具有单元内编辑功能的 PrimeFaces 数据表无法满足的需求。它可以通过编辑单个单元格来处理大量数据,而无需提交整个 sheet。使用 TAB 和 SHIFT+TAB 提供熟悉的展开sheet 导航和熟悉的展开sheet 体验。
功能包括:
- 快速细胞内编辑和验证
- Copy/Paste 范围选择包括 Copy/Paste 和填充
- 排序
- 过滤
- 固定列和行
- 可调整大小的列和行
- 可移动的列和行
- Ajax 更新和验证
基于 Handsoncode 的 Handsontable。
我有一个 Web 应用程序,它使用 JSF 中的数据表和 Primefaces 功能,以便它可以执行一些更动态的功能。在数据表中,我有包含可编辑数据的行。我的最终目标是让用户能够编辑该数据,单击保存按钮,然后将执行更新语句以替换数据库中的内容。问题是此时我不知道如何检测 arrayList 中对象的变化。
我做了一个例子,看看有没有人能解决我的困境。听说我有创建数据表的代码,数据表中是来自 ArrayList 的对象,每个对象包含三个不同的字符串。对象在数据表中是可编辑的。我至少需要能够检索在页面上编辑的对象的 ArrayList 索引。有了它,我可以形成一个新的编辑对象列表,并编写一个只对编辑的对象执行批量更新的方法(我的场景中的一个对象相当于数据库中的一行数据)。我以前的方法是遍历整个 ArrayList 并更新所有对象(行),但是,随着列表变大,这样做的成本会变得非常高。现在我有一个 primefaces 方法 onCellEdit,它告诉我一个以前的值和它被更改为的值,但无法查明对象已更改。任何帮助,将不胜感激。下面的代码是这样设置的,可以复制粘贴执行。
编辑: 在我的情况下,我不需要更新 ArrayList。这是使用页面上的输入以及 bean 的 getter 和 setter 自动完成的。我需要做的是知道编辑了哪些 对象(行) 以便我可以将它们拉到一边并执行数据库更新,其中我只更新编辑的内容。 ArrayList 是数据库中内容的镜像,但此处的目标是更新数据库以镜像已编辑的 ArrayList, 而无需 遍历整个 List。
Prod.java
public class Prod{
private String value1;
private String value2;
private String value3;
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getValue3() {
return value3;
}
public void setValue3(String value3) {
this.value3 = value3;
}
}
Listen.java
import java.io.IOException;
import java.util.ArrayList;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.primefaces.event.CellEditEvent;
import com.product.inventory.beans.Prod;
@ManagedBean(name = "listen")
@SessionScoped
public class Listen{
private ArrayList<Prod> products;
boolean firstEdit = true;
public Listen(){
}
public ArrayList<Prod> setup(){
ArrayList<Prod> result = new ArrayList<>();
int numObject = 100;
int iterations = 0;
while( iterations < numObject){
Prod prod = new Prod();
prod.setValue1("A" + iterations);
prod.setValue2("B" + iterations);
prod.setValue3("C" + iterations);
result.add(prod);
iterations = iterations + 1;
}
return result;
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
if(isFirstEdit()){
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new
FacesMessage(FacesMessage.SEVERITY_INFO,
"Note", "To confirm changes, please select 'Save Changes'
or they will not be saved.") );
this.setFirstEdit(false);
}
}
public void goTest(){
System.out.println("Initializing...");
this.products = setup();
ExternalContext ec = FacesContext.getCurrentInstance()
.getExternalContext();
try {
ec.redirect(ec.getRequestContextPath()
+ "/test.xhtml");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Table Structure Made");
}
public boolean isFirstEdit() {
return firstEdit;
}
public void setFirstEdit(boolean firstEdit) {
this.firstEdit = firstEdit;
}
public ArrayList<Prod> getProducts() {
return products;
}
public void setProducts(ArrayList<Prod> products) {
this.products = products;
}
}
test.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="form" method="post">
<p:growl id="msgs" showDetail="true" sticky="false">
</p:growl>
<div >
<p:dataTable id="products" var="prod" value="#{listen.products}"
scrollable="true" scrollHeight="900"
editable = "true" editMode="cell" widgetVar= "prodCell">
<p:ajax event="cellEdit" listener="#{listen.onCellEdit}"
update=":form:msgs"/>
<p:column filterBy="#{prod.value1}" filterMatchMode="contains"
style = "width: 300px;" headerText="Name">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#
{prod.value1}" /></f:facet>
<f:facet name="input"><p:inputTextarea rows="2" value="#
{prod.value1}" style = "width: 96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style = "width: 140px;" headerText="Vendor">
<p:cellEditor >
<f:facet name="output"><h:outputText value="#
{prod.value2}" /></f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{prod.value2}"
style="width:100%">
<f:selectItem itemValue="Y" itemLabel="Yes"/>
<f:selectItem itemValue="N" itemLabel="No"/>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style = "width: 275px;" headerText="Version Release">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#
{prod.value3}" /></f:facet>
<f:facet name="input"><p:inputTextarea rows="1" value="#
{prod.value3}" style = "width: 96%"/></f:facet>
</p:cellEditor>
</p:column>
<f:facet name="footer">
<div align = "left">
<p:commandButton value="post" action="#{tables.showChange}"
ajax="false"></p:commandButton>
</div>
</f:facet>
</p:dataTable>
</div>
<p:contextMenu for="products" widgetVar="pMenu">
<p:menuitem value="Edit Cell" icon="pi pi-search"
onclick="PF('prodCell').showCellEditor();return false;"/>
<p:menuitem value="Hide Menu" icon="pi pi-times"
onclick="PF('pMenu').hide()"/>
</p:contextMenu>
</h:form>
Index.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form method="post">
<h:commandButton value = "Contact Spreadsheet" ajax="false"
action="#{listen.goTest}" ></h:commandButton>
</h:form>
</h:body>
</html>
您想要的解决方案是您正在寻找的行为的 PrimeFaces Extensions Sheet 组件。
Sheet 满足了具有单元内编辑功能的 PrimeFaces 数据表无法满足的需求。它可以通过编辑单个单元格来处理大量数据,而无需提交整个 sheet。使用 TAB 和 SHIFT+TAB 提供熟悉的展开sheet 导航和熟悉的展开sheet 体验。
功能包括:
- 快速细胞内编辑和验证
- Copy/Paste 范围选择包括 Copy/Paste 和填充
- 排序
- 过滤
- 固定列和行
- 可调整大小的列和行
- 可移动的列和行
- Ajax 更新和验证
基于 Handsoncode 的 Handsontable。