11 Replies Latest reply on Mar 10, 2009 11:13 AM by ilya_shaikovsky

    Catching the correct row index for row deletion in rich:data

    andrew_st

      Hello,
      I would like to implement row deletion in rich:dataTable.

      I implemented this task by

      a) <h:commandButton actionListener="#{calculator.deleteParameter}" id="deleteParamButton" value="Delete Parameter" />

      b) <rich:contextMenu event="oncontextmenu" attachTo="parametersTable" submitMode="server" disableDefaultMenu="true">
      <rich:menuItem value="Delete Parameter" id="out"
      actionListener="#{calculator.deleteParameter}" reRender="parametersTable">
      <a4j:actionparam value="#{row}" assignTo="#{calculator.selectedRowIndex}"/>
      </rich:menuItem>
      </rich:contextMenu>


      The DataTable declaration is:

      <rich:dataTable value="#{calculator.parameterList}" var="parameters" id="parametersTable" rowKeyVar="row">

      and Calculator bean method:

      // parameterList() is the list of objects diplayed with rich:dataTable
      // private int selectedRowIndex;

      public void deleteParameter(ActionEvent event) {
      getParameterList().remove(selectedRowIndex);
      }


      For some reason both choosing €œDelete Parameter� from the context menu and clicking the button removes the 1st row in the table, not the one with the focus.

      It looks like <a4j:actionparam value="#{row}" assignTo="#{calculator.selectedRowIndex}"/> does not transfer correct parameter to bean as button and contextMenu bring the same result.

      Would you please comment how to correct the code?

      Kind regards

        • 1. Re: Catching the correct row index for row deletion in rich:
          nbelaevski

          Try this:

          <a4j:actionparam actionListener="#{calculator.deleteParameter}" ...>


          • 2. Re: Catching the correct row index for row deletion in rich:
            andrew_st

            Unfortunately it does not help :(

            If I add actionListener="#{calculator.deleteParameter}" to a4j:actionparam and remove it from rich:menuItem then the result is the same - the first row is deleted.

            If I add actionListener="#{calculator.deleteParameter}" to a4j:actionparam and leave it inside rich:menuItem then all the rows are deleted.

            • 3. Re: Catching the correct row index for row deletion in rich:
              nbelaevski
              • 4. Re: Catching the correct row index for row deletion in rich:

                Hi andrew_st, I remember that sometimes I've also got similar behaviour in my rich:dataTable. I believe I've changed only from actionListener to action.
                There are something like race conditions....I've traced this, that the based rowIndex for deletion wasn't set correctly before the call of the deletion method.
                Other problemsource was the usage of DataModel => there I've also most time strange behaviours.....maybe I've used this not correctly but currently I only work with normal List.....8-}

                currently my favorite for deletion stuff in rich:datatable is something like the following:

                <a4j:support id="calc_width" event="onchange" reRender="m_quadrat,m_cubic,weight"
                 ajaxSingle="true" action="#{elementlistItemHandler.changeWidth}">
                 <f:setPropertyActionListener value="#{record.oid}" target="#{elementlistItemHandler.oidForArticleSelection}" />
                 </a4j:support>


                I'm currently in love with the f:setPropertyActionListener - this works well for my programming style.

                regards
                rschoeler

                • 5. Re: Catching the correct row index for row deletion in rich:
                  andrew_st

                  Hi rschloeler,
                  hello nick

                  thank you for your attention to my problem and giving me some advice.

                  Would you please check my code again with the corrections I have made taking your advise into action:

                  Bean:

                  private int selectedRowIndex;
                  ...
                  public void deleteParameter(ActionEvent event) {
                  getParameterList().remove(selectedRowIndex);
                  }

                  JSP-page:

                  <rich:dataTable value="#{calculator.parameterList}" var="parameters" id="parametersTable" rowKeyVar="row">
                  ...
                  <a4j:commandButton actionListener="#{calculator.deleteParameter}" reRender="parametersTable"
                  id="deleteParamButton" value="Delete row€">
                  <f:setPropertyActionListener value="#{row}" target="#{calculator.selectedRowIndex}" />
                  </a4j:commandButton>
                  ...
                  </rich:dataTable>

                  I tried to assign both action and actionListener to a4j:commandButton but ... the result is still the same - 1st row is deleted, not the one clicked.

                  I'm sorry to say that I have killed almost two days, still do not understand why this does not work as expected.
                  Is having value="#{row}" as attribute to request sent in my example by a4j:commandButton and rowKeyVar="row" as attribute to rich:dataTable is all what is needed to catch the index of the row with the focus?
                  How this thing rowKeyVar="row" / value="#{row}" works actually?

                  Please advise if you can.


                  • 6. Re: Catching the correct row index for row deletion in rich:
                    nbelaevski

                    Hello,

                    Data table creates request-scoped variable for rowKeyVar. This variable is available only for components nested inside the table. When nested components are processed (e.g. decoded) or rendered, data table assigns corresponding values to rowKeyVar/var before processing nested components.

                    f:setPropertyActionListener works solely on the server, a4j:actionParam encodes parameter value to the client and then decodes it back on submit.

                    • 7. Re: Catching the correct row index for row deletion in rich:
                      andrew_st

                      Thank you very much, Nick

                      But what does follow from your comparison of f:setPropertyActionListener and a4j:actionParam?

                      Did you mean that
                      inside a4j:commandButton it is recommended to use a4j:actionParam
                      while
                      inside h:commandButton it is recommended to use f:setPropertyActionListener (and a4j:support for event="onclick") ?

                      Anyway whichever variant I try I still manage to delete the 1st row, not the one that I need to delete (the one where I have just clicked).

                      :( :( :(

                      • 8. Re: Catching the correct row index for row deletion in rich:
                        nbelaevski

                         

                        Did you mean that
                        inside a4j:commandButton it is recommended to use a4j:actionParam
                        while
                        inside h:commandButton it is recommended to use f:setPropertyActionListener (and a4j:support for event="onclick") ?
                        No, you can use any you like, these components work well either with h:* or a4j:* command components.

                        Can you please post full page/bean code reproducing the issue? I need something runnable to reproduce the problem.

                        • 9. Re: Catching the correct row index for row deletion in rich:
                          andrew_st

                          Hi Nick,
                          Please let me return to the issue of correct row deletion.

                          If I understood correct, you would like to see full jsp and bean code.
                          Below they are:

                          JSP

                          <%@page contentType="text/html" pageEncoding="UTF-8"%>
                          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                          "http://www.w3.org/TR/html4/loose.dtd">


                          <?xml version="1.0" encoding="ISO-8859-1" ?>

                          <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
                          <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

                          <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
                          <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>



                          Calculator Application

                          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

                          .inplace{
                          border: none;
                          }

                          fieldset, #parametersButtons, #setCoursesButton, #getCoursesButton {
                          margin-top:10px;
                          }

                          legend{
                          font-weight:bolder;
                          }

                          #setCoursesButton, #calculateButton {
                          margin-left:10px; margin-right:10px;
                          }

                          .pic{
                          margin-bottom: -4px;
                          margin-right: 2px;
                          }

                          #container {
                          width: 840px;
                          margin: 8px auto;
                          background: #fff;
                          }

                          #setCoursesTable {
                          width:100%;
                          }

                          #parametersDiv, #parametersButtons {
                          text-align:center;
                          }

                          p{
                          font-size:12px;
                          font-family:sans-serif;
                          }




                          <f:view>
                          <a4j:form>

                          <%--<f:loadBundle basename="LocalizationResources" var="bundle"/>--%>
                          <rich:toolBar height="26" itemSeparator="grid">
                          <rich:toolBarGroup>
                          <a4j:commandLink actionListener="#{calculator.loadCourse}">
                          <h:graphicImage id="open" value="/images/icons/create_folder.gif" styleClass="pic"/>
                          <h:outputLabel value="Open" for="open" />
                          </a4j:commandLink>
                          </rich:toolBarGroup>
                          <rich:toolBarGroup>
                          <a4j:commandLink actionListener="#{calculator.saveCourse}">
                          <h:graphicImage id="save" value="/images/icons/save.gif" styleClass="pic"/>
                          <h:outputLabel value="Save" for="save" />
                          </a4j:commandLink>
                          </rich:toolBarGroup>
                          </rich:toolBar>

                          Set rates





                          <rich:calendar id="myCalendar" value="#{calculator.selectedDate}">
                          <a4j:support event="onchanged" reRender="euroRate, usdRate" />
                          </rich:calendar>
                          <%-- var 2
                          <rich:calendar popup="true" todayControlMode="hidden" enableManualInput="false" isDayEnabled="" value="#{calculator.selectedDate}" currentDateChangeListener="#{calculator.getCourse}">
                          <a4j:support event="ondateselected" action="#{calculator.getCourse}"/>
                          <a4j:support event="onchanged" action="#{calculator.getCourse}"/>
                          </rich:calendar>
                          --%>
                          <rich:spacer style="display:block" height="6px" />

                          <a4j:commandButton id="getCoursesButton" value="Get rates" actionListener="#{calculator.fetchCourse}" reRender="euroRate, usdRate" />






                          <h:outputLabel value="Euro" for="euroRate" />

                          <%--
                          <h:inputText id="euroRate1" value="#{calculator.euroRate}">
                          <a4j:support actionListener="#{calculator.checkFieldEuro}" event="onkeyup" />
                          </h:inputText>
                          --%>
                          <rich:inplaceInput id="euroRate" value="#{calculator.euroRate}"
                          selectOnEdit="true" editEvent="onclick"
                          changedHoverClass="hover" viewHoverClass="hover"
                          viewClass="inplace" changedClass="inplace"
                          validator="#{calculator.checkFieldEuro}" showControls="true"
                          minInputWidth="120px" maxInputWidth="120px">
                          <%-- these two tags work in pair
                          <f:validateLength minimum="3" maximum="12"/>
                          <rich:ajaxValidator event="onblur"/>
                          --%>
                          <rich:toolTip for="euroRate" value="Допу�тимые значени� - целые и дробные � разделителем зап�той либо точкой"/>
                          </rich:inplaceInput>
                          <%--
                          <h:inputText id="euroRate" value="#{calculator.euroRate}">
                          <a4j:support actionListener="#{calculator.checkFieldEuro}" event="onkeyup" />
                          </h:inputText>
                          --%>

                          <rich:message for="euroRate" />


                          <h:outputLabel value="USD" for="usdRate" />

                          <rich:inplaceInput id="usdRate" value="#{calculator.usdRate}"
                          selectOnEdit="true" editEvent="onclick"
                          changedHoverClass="hover" viewHoverClass="hover"
                          viewClass="inplace" changedClass="inplace"
                          validator="#{calculator.checkFieldUsd}" showControls="true">
                          <rich:toolTip for="usdRate" value="Допу�тимые значени� - целые и дробные � разделителем зап�той либо точкой"/>
                          </rich:inplaceInput>

                          <rich:message for="usdRate" />


                          <%-- For some reason this version did not update outputText fields with currency rates


                          <h:outputLabel value="Кур� евро" for="euroRate" />
                          <h:outputText id="euroRate" binding="#{calculator.euroRateComponent}" />
                          <h:message for="euroRate" />


                          <h:outputLabel value="Кур� доллара" for="usdRate" />

                          <h:outputText id="usdRate" binding="#{calculator.usdRateComponent}" />
                          <h:message for="usdRate" />


                          --%>
                          <rich:spacer style="display:block" height="6px" />

                          <h:commandButton id="setCoursesButton" actionListener="#{calculator.setCourses}" value="Set rates" />








                          Формула ра�чета

                          <h:inputText id="formulaField" value="#{calculator.formula}" rendered="true" size="40" />
                          <rich:toolTip for="formulaField" value="Допу�тимые значени� - целые и дробные � разделителем зап�той либо точкой"/>
                          <rich:spacer width="8px" />
                          <h:commandButton id="calculateButton" actionListener="#{calculator.calculateResult}" value="=" />
                          <rich:spacer width="8px" />
                          <rich:inplaceInput id="resultField" value="#{calculator.result}" selectOnEdit="true" layout="inline" inputWidth="300px" maxInputWidth="400px" editEvent="onclick" viewClass="inplace" changedClass="inplace"></rich:inplaceInput>



                          Параметры
                          <!--
                          You may set parameters by:

                          clicking the button "Set rates"
                          clicking buttons below the table
                          clilcing context menu (right button click)


                          -->
                          <rich:contextMenu event="oncontextmenu" attachTo="parametersTable" submitMode="server" disableDefaultMenu="true">
                          <rich:menuItem value="Remove parameter" id="out" ajaxSingle="true" reRender="parametersTable" action="#{calculator.deleteParameter}">
                          <f:setPropertyActionListener value="#{row}" target="#{calculator.selectedRowIndex}" />
                          </rich:menuItem>
                          <rich:menuItem value="Add parameter" id="in"
                          actionListener="#{calculator.addParameter}" reRender="parametersTable">
                          </rich:menuItem>
                          </rich:contextMenu>
                          <%-- Another variant of context menu which deletes the 1st row instead of the one having focus
                          <rich:contextMenu event="oncontextmenu" attachTo="parametersTable" submitMode="server" disableDefaultMenu="true">
                          <rich:menuItem value="Удалить параметр" id="out" ajaxSingle="true" reRender="parametersTable">
                          <a4j:actionparam value="#{row}" assignTo="#{calculator.selectedRowIndex}" actionListener="#{calculator.deleteParameter}" />
                          </rich:menuItem>
                          <rich:menuItem value="Добавить параметр" id="in"
                          actionListener="#{calculator.addParameter}" reRender="parametersTable">
                          </rich:menuItem>
                          </rich:contextMenu>
                          --%>

                          <rich:dataTable value="#{calculator.parameterList}" var="parameters" id="parametersTable"
                          onRowMouseOver="this.style.backgroundColor='#F1F1F1'" onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
                          cellpadding="0" cellspacing="0" width="700" border="0"
                          rowKeyVar="row">
                          <h:column>
                          <f:facet name="header">
                          <h:outputText value="Name"/>
                          </f:facet>
                          <rich:inplaceInput value="#{parameters.name}" selectOnEdit="true" editEvent="onclick" layout="block" viewClass="inplace" changedClass="inplace">
                          </rich:inplaceInput>
                          </h:column>
                          <h:column>
                          <f:facet name="header">
                          <h:outputText value="Abbreviation"/>
                          </f:facet>
                          <rich:inplaceInput value="#{parameters.abbrev}" selectOnEdit="true" editEvent="onclick" layout="block" viewClass="inplace" changedClass="inplace">
                          </rich:inplaceInput>
                          </h:column>
                          <h:column>
                          <f:facet name="header">
                          <h:outputText value="Value"/>
                          </f:facet>
                          <rich:inplaceInput value="#{parameters.value}" selectOnEdit="true" editEvent="onclick" layout="block" viewClass="inplace" changedClass="inplace">
                          </rich:inplaceInput>
                          </h:column>
                          <h:column>
                          <f:facet name="header">
                          <h:outputText value="Notes" />
                          </f:facet>
                          <rich:inplaceInput value="#{parameters.comment}" selectOnEdit="true" editEvent="onclick" layout="block" viewClass="inplace" changedClass="inplace">
                          </rich:inplaceInput>
                          </h:column>
                          </rich:dataTable>


                          <h:commandButton actionListener="#{calculator.addParameter}" id="addParamButton" value="Add parameter" />
                          <a4j:commandButton actionListener="#{calculator.deleteParameter}" reRender="parametersTable"
                          id="deleteParamButton" value="Remove parameter">
                          <a4j:actionparam value="#{row}" assignTo="#{calculator.selectedRowIndex}" />
                          </a4j:commandButton>



                          </a4j:form>
                          </f:view>




                          JAVA

                          package com.sunriser.travelcostcalculator.ui;

                          import com.sunriser.travelcostcalculator.calculation.CalculatorFormula;
                          import com.sunriser.travelcostcalculator.calculation.Parameter;
                          import com.sunriser.travelcostcalculator.calculation.ParserAndCalculator;
                          import com.sunriser.travelcostcalculator.currency.CBRFCurrencyCourse;
                          import com.sunriser.travelcostcalculator.currency.Currency;
                          import com.sunriser.travelcostcalculator.currency.DateCurrencyCourse;
                          import com.sunriser.travelcostcalculator.exceptions.TravelCostException;
                          import com.sunriser.travelcostcalculator.xml.IXMLProcessor;
                          import com.sunriser.travelcostcalculator.xml.JDOMProcessor;
                          import java.io.IOException;
                          import java.math.BigDecimal;
                          import javax.faces.component.UIOutput;
                          import javax.swing.table.DefaultTableModel;

                          import java.beans.XMLEncoder;
                          import java.beans.XMLDecoder;
                          import java.io.BufferedInputStream;
                          import java.io.BufferedOutputStream;
                          import java.io.FileOutputStream;
                          import java.io.FileInputStream;

                          import org.richfaces.event.CurrentDateChangeEvent;
                          import java.util.ArrayList;
                          import java.util.List;
                          import java.util.Date;
                          import java.util.Iterator;
                          import java.util.ResourceBundle;
                          import javax.faces.event.ActionEvent;
                          import javax.faces.application.FacesMessage;
                          import javax.faces.component.UIComponent;
                          import javax.faces.context.FacesContext;
                          import javax.faces.validator.ValidatorException;

                          public class Calculator {

                          private String euroRate;
                          private String usdRate;
                          private String formula;
                          private String result;
                          List parameterList = new ArrayList();
                          private Date selectedDate;
                          private int selectedRowIndex;

                          public void setEuroRate(String euroRate) {
                          this.euroRate = euroRate;
                          }

                          public void setFormula(String formula) {
                          this.formula = formula;
                          }

                          public void setResult(String result) {
                          this.result = result;
                          }

                          public void setUsdRate(String usdRate) {
                          this.usdRate = usdRate;
                          }

                          public void setSelectedDate(Date selectedDate) {
                          this.selectedDate = selectedDate;
                          }

                          public void setSelectedRowIndex(int selectedRowIndex) {
                          this.selectedRowIndex = selectedRowIndex;
                          }

                          public int getSelectedRowIndex() {
                          return selectedRowIndex;
                          }

                          public Date getSelectedDate() {
                          return selectedDate;
                          }

                          public String getFormula() {
                          return formula;
                          }

                          public String getResult() {
                          return result;
                          }

                          public String getEuroRate() {
                          return euroRate;
                          }

                          public String getUsdRate() {
                          return usdRate;
                          }

                          public List getParameterList() {
                          return parameterList;
                          }

                          public void setParameterList(List parameterList) {
                          this.parameterList = parameterList;
                          }
                          UIOutput euroRateComponent = null;
                          UIOutput usdRateComponent = null;

                          public UIOutput getEuroRateComponent() {
                          return this.euroRateComponent;
                          }

                          public void setEuroRateComponent(UIOutput euroRateComponent) {
                          this.euroRateComponent = euroRateComponent;
                          }

                          public UIOutput getUsdRateComponent() {
                          return this.usdRateComponent;
                          }

                          public void setUsdRateComponent(UIOutput usdRateComponent) {
                          this.usdRateComponent = usdRateComponent;
                          }

                          // Backing Bean must have a no-arg constructor !
                          public Calculator() {
                          }
                          private ResourceBundle bundle = ResourceBundle.getBundle("messages");

                          /* Метод получени� и у�тановки полей � кур�ами валют на о�нове binding к �кземпл�рам компонентов
                          *
                          public void fetchCourse(ActionEvent event) {

                          Thread t = new Thread() {

                          public void run() {
                          CBRFCurrencyCourse cbrfCourse = new CBRFCurrencyCourse();
                          DateCurrencyCourse course = null;
                          Date dateLocal = new Date(System.currentTimeMillis());
                          System.out.println("Пользователь выбрал дату: " + dateLocal);
                          try {
                          course = cbrfCourse.getDateCurrencyCourse(dateLocal);
                          euroRateComponent.setValue(Double.toString(course.getCurrency().get(Currency.EUR)));
                          usdRateComponent.setValue(Double.toString(course.getCurrency().get(Currency.USD)));
                          System.out.println("У�тановлен кур� евро: " + getEuroRateComponent().getValue());
                          System.out.println("У�тановлен кур� доллара: " + getUsdRateComponent().getValue());
                          } catch (TravelCostException ex) {
                          String message = bundle.getString(ex.getResource());
                          //JOptionPane.showMessageDialog(null, message, bundle.getString("error"), JOptionPane.ERROR_MESSAGE);
                          } finally {
                          //dlg.setVisible(false);
                          }
                          }
                          };

                          t.start();
                          //dlg.setVisible(true);
                          }
                          */
                          public void fetchCourse(ActionEvent event) {

                          CBRFCurrencyCourse cbrfCourse = new CBRFCurrencyCourse();
                          DateCurrencyCourse course = null;
                          //System.out.println("The user selected date: " + getSelectedDate());
                          try {
                          course = cbrfCourse.getDateCurrencyCourse(getSelectedDate());
                          setEuroRate(Double.toString(course.getCurrency().get(Currency.EUR)));
                          setUsdRate(Double.toString(course.getCurrency().get(Currency.USD)));
                          System.out.println("Euro rate: " + getEuroRate());
                          System.out.println("USD rate: " + getUsdRate());
                          } catch (TravelCostException ex) {
                          String message = bundle.getString(ex.getResource());
                          } finally {
                          //progress bar dissappears
                          }
                          }

                          public void setCourses(ActionEvent event) {

                          Double euroLocal = Double.parseDouble(getEuroRate().replace(',', '.'));
                          Double usdLocal = Double.parseDouble(getUsdRate().replace(',', '.'));
                          Parameter currencyUSD = new Parameter("Кур� доллара", "USD", usdLocal, "");
                          Parameter currencyEuro = new Parameter("Кур� евро", "EU", euroLocal, "");

                          parameterList.clear();
                          parameterList.add(currencyUSD);
                          parameterList.add(currencyEuro);

                          for (Iterator iterParam = parameterList.iterator(); iterParam.hasNext();) {
                          Parameter param = iterParam.next();
                          System.out.println(param.getValue());
                          }
                          }

                          public void addParameter(ActionEvent event) {

                          Parameter param = new Parameter();
                          parameterList.add(param);

                          }

                          public void deleteParameter(ActionEvent event) {
                          getParameterList().remove(selectedRowIndex);
                          }

                          /* Set of functions verifying if the manually entered values are currency rates indeed */
                          public boolean isDoubleNumber(String num) {
                          try {
                          Double.parseDouble(num);
                          } catch (NumberFormatException nfe) {
                          return false;
                          }
                          return true;
                          }

                          public void checkFieldEuro(FacesContext context, UIComponent component, Object value) throws ValidatorException {
                          if (value == null) {
                          return;
                          }
                          String euroRateLocal = value.toString().replace(',', '.');
                          //System.out.println("Введен кур� евро (по�ле toString): " + euroRateLocal);
                          if (!isDoubleNumber(euroRateLocal)) {
                          throw new ValidatorException(new FacesMessage("Данные не �вл�ют�� чи�ленными", null));
                          }
                          }

                          public void checkFieldUsd(FacesContext context, UIComponent component, Object value) throws ValidatorException {
                          if (value == null) {
                          return;
                          }
                          String usdRateLocal = value.toString().replace(',', '.');
                          //System.out.println("Введен кур� доллара: " + usdRateLocal);
                          if (!isDoubleNumber(usdRateLocal)) {
                          throw new ValidatorException(new FacesMessage("Данные не �вл�ют�� чи�ленными", null));
                          }
                          }

                          public void checkFormulaField(FacesContext context, UIComponent component, Object value) throws ValidatorException {
                          if (value == null) {
                          return;
                          }
                          String formulaLocal = value.toString().replace(',', '.');
                          if (!isDoubleNumber(formulaLocal)) {
                          throw new ValidatorException(new FacesMessage("Данные не �вл�ют�� чи�ленными", null));
                          }
                          }

                          public void calculateResult(ActionEvent event) {
                          CalculatorFormula calculatorFormulaLocal = new CalculatorFormula();
                          ParserAndCalculator pac = new ParserAndCalculator();

                          for (Parameter s : getParameterList()) {
                          calculatorFormulaLocal.getParams().add(s);
                          }


                          for (Parameter s : calculatorFormulaLocal.getParams()) {
                          System.out.println(s.getName());
                          }



                          Double sum = new Double(0.0);
                          String formulaLocal = getFormula();
                          System.out.println("В поле формул введено: " + formulaLocal);
                          String messages = new String();
                          if (formulaLocal != null && !formulaLocal.equals("") && calculatorFormulaLocal.getParams().isEmpty() == false) {
                          try {
                          calculatorFormulaLocal.setFormula(formulaLocal);
                          System.out.println("CalculatorFormula: " + calculatorFormulaLocal.getFormula());
                          sum = pac.getSum(calculatorFormulaLocal);
                          BigDecimal x = new BigDecimal(sum.toString());
                          x = x.setScale(2, BigDecimal.ROUND_HALF_UP);
                          setResult(x.toString());
                          System.out.println("Результат вычи�лений: " + getResult());
                          } catch (TravelCostException tce) {
                          messages += tce.getResource();
                          setResult(messages);
                          }
                          } else {
                          //jLabel3.setText(bundle.getString("incorrect_data"));
                          }

                          }
                          /* End of the set of functions verifying if the manualy entered values are currency rates indeed */

                          /* SET OF FUNCTIONS DEALING WITH XML */
                          public void saveCourse(ActionEvent event) {
                          TableData localTableData = new TableData();
                          try {
                          XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("D:\\Andrey/MyXML.xml")));
                          for (Parameter s : getParameterList()) {
                          localTableData.getParameterList().add(s);
                          }
                          encoder.writeObject(localTableData);
                          encoder.close();
                          } catch (Exception e) {
                          e.printStackTrace();
                          }
                          }

                          public void loadCourse(ActionEvent event) {
                          // list is a list of Objects returned as a result of XML conversion
                          TableData listParameter = new TableData();
                          try {
                          XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream("D:\\Andrey/MyXML.xml")));
                          try {
                          while (true) {
                          listParameter.getParameterList().add((Parameter) (decoder.readObject()));
                          }
                          } catch (ArrayIndexOutOfBoundsException exception) {
                          } finally {
                          decoder.close();
                          }
                          parameterList.clear();
                          for (Parameter i : listParameter.getParameterList()) {
                          parameterList.add(i);
                          System.out.println(i.getName() + " " + i.getValue() + " " + i.getAbbrev() + " " + i.getComment());
                          }
                          //parameterList.setParameterList((List)listParameter.getParameterList());
                          } catch (Exception e) {
                          e.printStackTrace();
                          }
                          }

                          private void convertAllToCalculatorFormula() {
                          calculatorFormula.setFormula(formulaField.getText());
                          convertTableParams();
                          }

                          private void convertTableParams() {
                          DefaultTableModel tableModel = (DefaultTableModel) paramsTable.getModel();
                          calculatorFormula.getParams().clear();
                          int rowCount = tableModel.getRowCount();
                          for (int i = 0; i < rowCount; i++) {
                          Parameter parameter = new Parameter();
                          parameter.setName((String) tableModel.getValueAt(i, 0));
                          parameter.setAbbrev((String) tableModel.getValueAt(i, 1));
                          parameter.setValue((Double) tableModel.getValueAt(i, 2));
                          parameter.setComment((String) tableModel.getValueAt(i, 3));
                          calculatorFormula.getParams().add(parameter);
                          }
                          }

                          public void testParameterList(ActionEvent event) {
                          for (Parameter s : getParameterList()) {
                          System.out.println(s.getName() + " " + s.getValue());
                          }
                          }

                          private javax.swing.JButton addParamButton;
                          private javax.swing.JRadioButton autoRadioButton;
                          private javax.swing.ButtonGroup buttonGroup1;
                          private javax.swing.JButton calculateButton;
                          private javax.swing.JButton courseButton;
                          private com.toedter.calendar.JDateChooser dateChooser;
                          private javax.swing.JButton deleteParamsButton;
                          private javax.swing.JFormattedTextField euroField;
                          private javax.swing.JMenuItem exitMenuItem;
                          private javax.swing.JTextField formulaField;
                          private javax.swing.JButton getCourseButton;
                          private javax.swing.JLabel jLabel1;
                          private javax.swing.JLabel jLabel2;
                          private javax.swing.JLabel jLabel3;
                          private javax.swing.JMenu jMenu1;
                          private javax.swing.JMenuBar jMenuBar1;
                          private javax.swing.JPanel jPanel1;
                          private javax.swing.JPanel jPanel2;
                          private javax.swing.JPanel jPanel3;
                          private javax.swing.JScrollPane jScrollPane1;
                          private javax.swing.JSeparator jSeparator1;
                          private javax.swing.JMenuItem loadMenuItem;
                          private javax.swing.JRadioButton manualRadioButton;
                          private javax.swing.JMenuItem newMenuItem;
                          private javax.swing.JTable paramsTable;
                          private javax.swing.JFormattedTextField resultField;
                          private javax.swing.JMenuItem savaAsMenuItem;
                          private javax.swing.JMenuItem saveMenuItem;
                          private javax.swing.JFormattedTextField usdField;
                          private CalculatorFormula calculatorFormula;


                          public void handleDateChange2(CurrentDateChangeEvent event) {
                          Date date = event.getCurrentDate();
                          System.out.println(date);
                          }
                          }

                          Though this code is not sufficient for deployment :)


                          Thank you a lot for your time,
                          Andrey

                          • 10. Re: Catching the correct row index for row deletion in rich:
                            andrew_st

                            Nick,
                            I'm sorry for the badly formatted text.
                            I have saved the code as txt but it is still shown ugly in preview.
                            Andrey

                            • 11. Re: Catching the correct row index for row deletion in rich:
                              ilya_shaikovsky

                              andrew_st, b.t.w. have you checked the sample to which Nick pointed you earlier? It contains your case already implemented.

                              http://livedemo.exadel.com/richfaces-demo/richfaces/dataTable.jsf?tab=editDataTable&cid=1955287