我有一个使用 Primefaces 12 的 Web 应用程序。当我在 xhtml 文件中使用 dataTable 时,如果我填充其中一列并转到另一列,则可以正常工作。但是当我使用动态生成的数据表不起作用时,不要在
onEditarCeldaTablaProc
方法上输入,并且还会显示下一个错误:
GRAVE: java.lang.NullPointerException
at org.primefaces.event.CellEditEvent.resolveValue(CellEditEvent.java:106)
at org.primefaces.event.CellEditEvent.\<init\>(CellEditEvent.java:58)
at org.primefaces.event.CellEditEvent.\<init\>(CellEditEvent.java:62)
at org.primefaces.component.datatable.DataTable.queueEvent(DataTable.java:452)
at org.primefaces.behavior.ajax.AjaxBehaviorRenderer.decode(AjaxBehaviorRenderer.java:55)
at javax.faces.component.behavior.ClientBehaviorBase.decode(ClientBehaviorBase.java:134)
at org.primefaces.util.ComponentUtils.decodeBehaviors(ComponentUtils.java:256)
at org.primefaces.renderkit.CoreRenderer.decodeBehaviors(CoreRenderer.java:628)
at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:75)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:533)
at org.primefaces.component.api.UIData.processDecodes(UIData.java:140)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:629)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at org.primefaces.component.api.UIData.visitTree(UIData.java:715)
这是工作正常的 xhtml 文件的内容:
<f:facet name="header">
<p:toolbar id="tabla_BotoneraTablaProc" styleClass="toolbar-estilo-tabla-form-solicitud">
<p:toolbarGroup>
<p:outputLabel value="Pruebas" />
</p:toolbarGroup>
<p:toolbarGroup align="right">
<p:tooltip for="botonAnadirFilaTablaProc"
value="#{etiquetasSubvenciones['anadir.fila']}" showEffect="fade"
hideEffect="fade" hideEvent="mouseleave click"/>
<p:commandButton id="botonAnadirFilaTablaProc" styleClass="boton"
icon="fas fa-plus"
action="#{fichaFormularioConvocatoriaBean.onNuevaFilaTablaPruebaUno}"
update="@([id$=tablaPrueba])"
process="@this">
<f:setPropertyActionListener
value="formFichaSolicitud:fichaSolicitud:tablaPrueba"
target="#{fichaFormularioConvocatoriaBean.idDataTableActual}" />
</p:commandButton>
<p:tooltip for="botonEliminarFilaTablaProc"
value="#{etiquetasSubvenciones['borrar.fila']}" showEffect="fade"
hideEffect="fade" hideEvent="mouseleave click"/>
<p:commandButton id="botonEliminarFilaTablaProc" styleClass="boton"
icon="fas fa-minus"
action="#{fichaFormularioConvocatoriaBean.onEliminarFilaTablaProc}">
<p:confirm header="#{etiquetas['eliminar.titulo']}"
message="#{etiquetas['eliminar.mensaje']}"
icon="ui-icon-alert" />
</p:commandButton>
</p:toolbarGroup>
</p:toolbar>
</f:facet>
<p:dataTable id="tablaPruebaUno" widgetVar="tablaPruebaUno" var="listaColsTablaProc"
value="#{fichaFormularioConvocatoriaBean.lstPruebaUno}"
lazy="false"
rowKey="#{listaColsTablaProc.hashCode()}"
selection="#{fichaFormularioConvocatoriaBean.pruebaSeleccionadaUno}"
emptyMessage="#{etiquetas['emptyMessage']}" reflow="true"
editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{fichaFormularioConvocatoriaBean.onEditarCeldaTablaProc}"/>
<p:column selectionMode="single" style="width:4%;text-align:center"/>
<p:column
headerText="Columna1" style="text-align:center">
<p:cellEditor>
<f:facet name="output">
<h:outputText id="listaColsTablaCol1" value="#{listaColsTablaProc.id}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{listaColsTablaProc.id}" style="width: 100%;">
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<p:column
headerText="Columna2" style="text-align:center">
<p:cellEditor>
<f:facet name="output">
<h:outputText id="listaColsTablaCol2" value="#{listaColsTablaProc.nombre}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{listaColsTablaProc.nombre}" style="width: 100%;">
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
这是动态实现部分的代码:
属性:
private static final String EVT_AJAX_CELL_EDIT = "cellEdit";
AjaxBehavior pAjaxCellEdit;
String idDataTableActual;
List<Prueba> lstPrueba;
Prueba pruebaSeleccionada;
List<Prueba> lstPruebaUno;
Prueba pruebaSeleccionadaUno;
..............
在构造函数中:
pAjaxCellEdit = new AjaxBehavior();
MethodExpression meEditCell = expFactory.createMethodExpression(elContext, "#{fichaFormularioConvocatoriaBean.onEditarCeldaTablaProc}", getClass(), new Class<?>[] {CellEditEvent.class});
pAjaxCellEdit.addAjaxBehaviorListener(new AjaxBehaviorListenerImpl(meEditCell, meEditCell));
另一种方法:
tab.getChildren().add(toolBarCumplimentarDos("TablaPrueba", "1", PANEL_BOT_TBL_FORM_SOLICITUD, TOOLBAR_TBL_FORM_SOLICITUD));
tab.getChildren()
.add(dataTableCumplimentarDos(
"#{fichaFormularioConvocatoriaBean.lstPrueba}",
"#{fichaFormularioConvocatoriaBean.pruebaSeleccionada}",
lstPrueba));
调用的方法:
private Panel toolBarCumplimentarDos(String titulo, String idTabla, String estiloPanel, String estiloToolBar) {
Panel panel = new Panel();
Toolbar toolBar = new Toolbar();
ToolbarGroup toolBarGroupTitle= new ToolbarGroup();
ToolbarGroup toolBarGroupButtons= new ToolbarGroup();
OutputLabel outputLabel = new OutputLabel();
Tooltip tooltipAdd = new Tooltip();
Tooltip tooltipDel = new Tooltip();
CommandButton comButAdd = new CommandButton();
CommandButton comButDel = new CommandButton();
ValueExpression target = expFactory.createValueExpression(elContext, "#{fichaFormularioConvocatoriaBean.idDataTableActual}", String.class);
ValueExpression value = expFactory.createValueExpression(TABVIEW_SOLICITUDES + TABVIEW_BLOQUE_DATOS + ":" + TBL_SOLICITUD_PREF_ID_DT + idTabla, String.class);
ActionListener handler = new SetPropertyActionListenerImpl(target , value);
tooltipAdd.setFor(PREF_ETQ_BOTON_ANADIR_FILA + idTabla);
tooltipAdd.setValue(VALUE_TOOLTIP_BOTON_ANADIR_FILA);
tooltipAdd.setShowEffect(SHOWEF_TOOLTIP);
tooltipAdd.setHideEffect(HIDEEF_TOOLTIP);
comButAdd.setId(PREF_ETQ_BOTON_ANADIR_FILA + idTabla);
comButAdd.setIcon(ICONO_ANADIR);
comButAdd.setStyleClass("boton");
comButAdd.setActionExpression(expFactory.createMethodExpression(elContext, "#{fichaFormularioConvocatoriaBean.onNuevaFilaTablaPrueba}", getClass(), new Class[0]));
comButAdd.addActionListener(handler);
comButAdd.setUpdate("@([id$=" + TBL_SOLICITUD_PREF_ID_DT + idTabla + "])");
comButAdd.setProcess("@this");
tooltipDel.setFor(PREF_ETQ_BOTON_BORRAR_FILA + idTabla);
tooltipDel.setValue(VALUE_TOOLTIP_BOTON_BORRAR_FILA);
tooltipDel.setShowEffect(SHOWEF_TOOLTIP);
tooltipDel.setHideEffect(HIDEEF_TOOLTIP);
comButDel.setId(PREF_ETQ_BOTON_BORRAR_FILA + idTabla);
comButDel.setIcon(ICONO_ELIMINAR);
comButDel.setStyleClass("boton");
comButDel.setActionExpression(expFactory.createMethodExpression(elContext, "#{fichaFormularioConvocatoriaBean.onEliminarFilaTablaProc}", getClass(), new Class[0]));
comButDel.setValueExpression("disabled", expFactory.createValueExpression(elContext, "#{fichaFormularioConvocatoriaBean.listaBloquesDatosFormularioCumplimentar.get(0).getObjetos().get(0).tablaBloqueDatosDto.detalles.filaSeleccionada == null}", Boolean.class));
outputLabel.setValue(titulo);
toolBarGroupTitle.getChildren().add(outputLabel);
toolBarGroupButtons.getChildren().add(tooltipAdd);
toolBarGroupButtons.getChildren().add(comButAdd);
toolBarGroupButtons.getChildren().add(tooltipDel);
toolBarGroupButtons.getChildren().add(comButDel);
toolBar.getChildren().add(toolBarGroupTitle);
toolBar.getChildren().add(toolBarGroupButtons);
toolBar.setStyleClass(estiloToolBar);
panel.setStyleClass(estiloPanel);
panel.getFacets().put("header", toolBar);
return panel;
}
private DataTable dataTableCumplimentarDos(String filasValueExpr, String filaSeleccionadaValueExpr, List<Prueba> tabla) {
DataTable dataTable = new DataTable();
List<UIColumn> columnas = new ArrayList<UIColumn>();
CellEditor cellEd = new CellEditor();
Column colUI;
String var = TBL_SOLICITUD_PREF_VAR + "1";
String idDataTable = TBL_SOLICITUD_PREF_ID_DT + "1";
colUI = new Column();
colUI.setSelectionMode(TBL_SOLICITUD_SEL_MODE);
colUI.setStyle(TBL_SOLICITUD_SEL_STYLE);
columnas.add(colUI);
cellEd.getFacets().put("output", outputLabelCumplimentar("#{" + var + ".id}",""));
cellEd.getFacets().put("input", uiComponentCumplimentarDos(TipoDato.EnumTipoDato.ENTERO, "#{" + var + "", ".id}", null, true));
colUI = new Column();
colUI.setStyle(TBL_SOLICITUD_CELL_STYLE);
colUI.setHeaderText("Columna1");
colUI.getChildren().add(cellEd);
columnas.add(colUI);
cellEd = new CellEditor();
cellEd.getFacets().put("output", outputLabelCumplimentar("#{" + var + ".nombre}",""));
cellEd.getFacets().put("input", uiComponentCumplimentarDos(TipoDato.EnumTipoDato.ENTERO, "#{" + var + "", ".nombre}", null, true));
colUI = new Column();
colUI.setStyle(TBL_SOLICITUD_CELL_STYLE);
colUI.setHeaderText("Columna2");
colUI.getChildren().add(cellEd);
columnas.add(colUI);
dataTable.setColumns(columnas);
dataTable.setValueExpression("value", expFactory.createValueExpression(elContext, filasValueExpr, ArrayList.class));
dataTable.setLazy(false);
dataTable.setEditable(true);
dataTable.setEditMode("cell");
dataTable.setVar(var);
dataTable.setEmptyMessage(TBL_MSG_VACIA);
dataTable.setReflow(true);
dataTable.setValueExpression("rowKey", expFactory.createValueExpression(elContext, "#{" + var + ".hashCode()}", String.class));
dataTable.setValueExpression("selection", expFactory.createValueExpression(elContext, filaSeleccionadaValueExpr, ArrayList.class));
dataTable.setId(idDataTable);
dataTable.setWidgetVar(idDataTable);
dataTable.addClientBehavior(EVT_AJAX_CELL_EDIT, pAjaxCellEdit);
return dataTable;
}
你能帮我一下吗?
提前致谢
我正在尝试使用生成的动态数据表来实现单元格编辑。我希望有人可以帮助我。
我终于找到问题所在了。列必须作为子项添加到 dataTable 中,而不是使用 dataTable.setColumns(columnas)。所以 dataTable.getChildren().add(colUI) 就是解决方案。