/** Dynamic Display. */
 public void dynamicDisplay() {
   for (int i = 0; i < m_wEditors.size(); i++) {
     WEditor editor = m_wEditors.get(i);
     GridField mField = editor.getGridField();
     if (mField.isDisplayed(true)) {
       if (!editor.isVisible()) {
         editor.setVisible(true);
         if (mField.getVO().isRange) {
           // m_separators.get(i).setVisible(true);
           m_wEditors2.get(i).setVisible(true);
         }
       }
       boolean rw = mField.isEditablePara(true); // r/w - check if
       // field is Editable
       editor.setReadWrite(rw);
       editor.dynamicDisplay();
       if (mField.getVO().isRange) {
         WEditor editorRange = m_wEditors2.get(i);
         if (editorRange != null) {
           editorRange.setReadWrite(rw);
           editorRange.dynamicDisplay();
         }
       }
     } else if (editor.isVisible()) {
       editor.setVisible(false);
       if (mField.getVO().isRange) {
         // m_separators.get(i).setVisible(false);
         m_wEditors2.get(i).setVisible(false);
       }
     }
   }
 }
 /**
  * Editor Listener
  *
  * @param evt Event
  * @exception ValueChangeEvent if the recipient wishes to roll back.
  */
 public void valueChange(ValueChangeEvent evt) {
   if (evt.getSource() instanceof WEditor) {
     GridField changedField = ((WEditor) evt.getSource()).getGridField();
     if (changedField != null) {
       processDependencies(changedField);
       // future processCallout (changedField);
     }
   }
   String columnName = "";
   if (evt.getSource() instanceof WEditor) {
     WEditor wEditor = (WEditor) evt.getSource();
     columnName = wEditor.getGridField().getVO().Help;
   }
   processNewValue(evt.getNewValue(), columnName);
 } // valueChange
  /** @param e */
  public void valueChange(ValueChangeEvent e) {
    if (gridTab.isProcessed()) //  only active records
    {
      Object source = e.getSource();
      if (source instanceof WEditor) {
        // Elaine 2009/05/06
        WEditor editor = (WEditor) source;
        GridField gridField = editor.getGridField();

        if (gridField != null) {
          if (!gridField.isEditable(true)) {
            logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
            return;
          }
        } else if (!editor.isReadWrite()) {
          logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
          return;
        }
      } else {
        logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
        return;
      }
    } //  processed
    logger.config(
        "("
            + gridTab.toString()
            + ") "
            + e.getPropertyName()
            + "="
            + e.getNewValue()
            + " ("
            + e.getOldValue()
            + ") "
            + (e.getOldValue() == null ? "" : e.getOldValue().getClass().getName()));

    //  Get Row/Col Info
    GridTable mTable = gridTab.getTableModel();
    int row = gridTab.getCurrentRow();
    int col = mTable.findColumn(e.getPropertyName());
    //
    if (e.getNewValue() == null
        && e.getOldValue() != null
        && e.getOldValue().toString().length() > 0) //  some editors return "" instead of null
      //        	  this is the original code from GridController, don't know what it does there but
      // it breaks ignore button for web ui
      //            mTable.setChanged (true);
      mTable.setValueAt(e.getNewValue(), row, col);
    else {

      Object newValue = e.getNewValue();
      Integer newValues[] = null;

      if (newValue instanceof Integer[]) {
        newValues = ((Integer[]) newValue);
        newValue = newValues[0];

        if (newValues.length > 1) {
          Integer valuesCopy[] = new Integer[newValues.length - 1];
          System.arraycopy(newValues, 1, valuesCopy, 0, valuesCopy.length);
          newValues = valuesCopy;
        } else {
          newValues = null;
        }
      } else if (newValue instanceof Object[]) {
        logger.severe("Multiple values can only be processed for IDs (Integer)");
        throw new IllegalArgumentException(
            "Multiple Selection values not available for this field. " + e.getPropertyName());
      }

      mTable.setValueAt(newValue, row, col);
      //  Force Callout
      if (e.getPropertyName().equals("S_ResourceAssignment_ID")) {
        GridField mField = gridTab.getField(col);
        if (mField != null && mField.getCallout().length() > 0) {
          gridTab.processFieldChange(mField); //  Dependencies & Callout
        }
      }

      if (newValues != null && newValues.length > 0) {
        // Save data, since record need to be used for generating clones.
        if (!gridTab.dataSave(false)) {
          throw new AdempiereException("SaveError");
        }

        // Retrieve the current record ID
        int recordId = gridTab.getKeyID(gridTab.getCurrentRow());

        Trx trx = Trx.get(Trx.createTrxName(), true);
        trx.start();
        try {
          saveMultipleRecords(
              Env.getCtx(),
              gridTab.getTableName(),
              e.getPropertyName(),
              recordId,
              newValues,
              trx.getTrxName());
          trx.commit();
          gridTab.dataRefreshAll();
        } catch (Exception ex) {
          trx.rollback();
          logger.severe(ex.getMessage());
          throw new AdempiereException("SaveError");
        } finally {
          trx.close();
        }
      }
    }
  } // ValueChange