Example #1
0
  /**
   * Permite seleccionar un {@link PagoM}
   *
   * @param pagos
   * @return
   */
  public static PagoM seleccionarPagoM(List<Map<String, Object>> pagos) {
    final SelectorDePagoM selector =
        new SelectorDePagoM(GlazedLists.eventList(pagos)) {

          @Override
          protected String getHeaderDesc() {
            String pattern = "{0} ({1})";
            return MessageFormat.format(pattern, "Saldos a Favor", "Todos los Clientes");
          }

          protected TableFormat getTableFormat() {
            return new DisponiblesTableFormat();
          }

          @Override
          protected void decorateGrid(JXTable grid) {
            grid.getColumnExt("TIPO").setVisible(false);
            grid.getColumnExt("ORIGEN_ID").setVisible(false);
            grid.getColumnExt("NOTA_ID").setVisible(false);
          }
        };
    selector.setFiltros(true);
    selector.open();
    if (!selector.hasBeenCanceled()) {
      return selector.getSelected();
    } else return null;
  }
    public BodyLayerStack(List<T> values, IColumnPropertyAccessor<T> columnPropertyAccessor) {
      // wrapping of the list to show into GlazedLists
      // see http://publicobject.com/glazedlists/ for further information
      EventList<T> eventList = GlazedLists.eventList(values);
      TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);

      // use the SortedList constructor with 'null' for the Comparator
      // because the Comparator
      // will be set by configuration
      SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
      // wrap the SortedList with the FilterList
      this.filterList = new FilterList<>(sortedList);

      this.bodyDataProvider = new ListDataProvider<>(this.filterList, columnPropertyAccessor);
      this.bodyDataLayer = new DataLayer(getBodyDataProvider());

      // layer for event handling of GlazedLists and PropertyChanges
      GlazedListsEventLayer<T> glazedListsEventLayer =
          new GlazedListsEventLayer<>(getBodyDataLayer(), this.filterList);

      this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
      ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());

      setUnderlyingLayer(viewportLayer);
    }
Example #3
0
 public static PlaylistTableModel create(RobonoboFrame frame, Playlist p, boolean canEdit) {
   List<Track> trax = new ArrayList<Track>();
   for (String sid : p.getStreamIds()) {
     trax.add(frame.ctrl.getTrack(sid));
   }
   EventList<Track> el = GlazedLists.eventList(trax);
   return new PlaylistTableModel(frame, p, canEdit, el, null);
 }
Example #4
0
 private JComboBox buildLineaControl() {
   final JComboBox box = new JComboBox();
   final EventList source =
       GlazedLists.eventList(
           ServiceLocator2.getHibernateTemplate().find("from Linea l order by l.nombre"));
   final TextFilterator filterator = GlazedLists.textFilterator(new String[] {"nombre"});
   AutoCompleteSupport support = AutoCompleteSupport.install(box, source, filterator);
   support.setFilterMode(TextMatcherEditor.STARTS_WITH);
   support.setCorrectsCase(true);
   return box;
 }
Example #5
0
 @SuppressWarnings("unchecked")
 private void registrarAsientos(final GCompra compra) {
   final EventList<GCompraDet> eventList = GlazedLists.eventList(compra.getPartidas());
   final GroupingList groupList =
       new GroupingList(
           eventList, GlazedLists.beanPropertyComparator(GCompraDet.class, "sucursal.clave"));
   for (int index = 0; index < groupList.size(); index++) {
     List<GCompraDet> row = groupList.get(index);
     registrarAsientos(row);
   }
 }
  @Override
  protected List<Embarque> findData() {
    String hql = "from Embarque e where e.regreso is null";
    List<Embarque> data = ServiceLocator2.getHibernateTemplate().find(hql);
    hql = "from Embarque e where date(e.regreso) between ? and ?";
    data.addAll(
        ServiceLocator2.getHibernateTemplate()
            .find(hql, new Object[] {periodo.getFechaInicial(), periodo.getFechaFinal()}));

    UniqueList<Embarque> unidata =
        new UniqueList<Embarque>(
            GlazedLists.eventList(data), GlazedLists.beanPropertyComparator(Embarque.class, "id"));
    return unidata;
  }
  /** Create a new event list view example. */
  public EventListViewExample() {
    super();
    setBorder(new EmptyBorder(12, 12, 12, 12));

    List<String> strings = new ArrayList<String>();
    for (int i = 0; i < 100; i++) {
      strings.add("Value " + i);
    }
    eventList = GlazedLists.eventList(strings);

    addField("Count label:", new CountLabel<String>(eventList));
    addField("Elements label:", new ElementsLabel<String>(eventList));
    addLabel("Elements summary:");

    UnaryFunction<String, JComponent> modelToLabel =
        new UnaryFunction<String, JComponent>() {
          // todo:  this really aught to be a list synchronized with the event list
          private final Map<String, JComponent> cache = new HashMap<String, JComponent>();

          @Override
          public JComponent evaluate(final String element) {
            if (!cache.containsKey(element)) {
              cache.put(element, new JLabel(element));
            }
            return cache.get(element);
          }
        };

    addField(new ElementsSummary<String>(eventList, modelToLabel));
    addSpacing(12);
    addLabel("Identifiable elements summary:");
    addField(new IdElementsSummary<String>(eventList));
    addSpacing(12);
    addFinalField(createLowerPanel());

    Timer t =
        new Timer(
            5000,
            new ActionListener() {
              @Override
              public void actionPerformed(final ActionEvent e) {
                if (!eventList.isEmpty()) {
                  eventList.remove(0);
                }
              }
            });
    t.setRepeats(true);
    t.start();
  }
Example #8
0
  /**
   * Selector para {@link PagoM}
   *
   * @param c
   * @param pagos
   * @return
   */
  public static PagoM seleccionarPagoM(final Cliente c, final List<PagoM> pagos) {
    final SelectorDePagoM selector =
        new SelectorDePagoM(GlazedLists.eventList(pagos)) {

          @Override
          protected String getHeaderDesc() {
            String pattern = "{0} ({1})";
            return MessageFormat.format(pattern, c.getNombre(), c.getClave());
          }
        };
    selector.open();
    if (!selector.hasBeenCanceled()) {
      return selector.getSelected();
    } else return null;
  }
 /**
  * Registra los gastos agrupandolos por rubro y sucursal
  *
  * @param compra
  * @param registros
  */
 @SuppressWarnings("unchecked")
 public void registrarGastosAgrupados(
     final GCompra compra, final Poliza poliza, final String factura) {
   final EventList<GCompraDet> eventList = GlazedLists.eventList(compra.getPartidas());
   final Comparator<GCompraDet> c1 =
       GlazedLists.beanPropertyComparator(GCompraDet.class, "rubro.id");
   final Comparator<GCompraDet> c2 =
       GlazedLists.beanPropertyComparator(GCompraDet.class, "sucursal.clave");
   Comparator<GCompraDet>[] comps = new Comparator[] {c1, c2};
   final GroupingList groupList =
       new GroupingList(eventList, GlazedLists.chainComparators(Arrays.asList(comps)));
   for (int index = 0; index < groupList.size(); index++) {
     List<GCompraDet> row = groupList.get(index);
     registrarGasto(row, poliza, factura);
   }
 }
  /**
   * Genera un pago con {@link NotaDeCredito} a un grupo de ventas
   *
   * @param c
   * @param ventas
   */
  public List<Venta> registrarPagoConNota(final Cliente c, final List<Venta> ventas) {

    // Filtramos las ventas con saldo
    CXCFiltros.filtrarVentasConSaldo(ventas);
    final List<Venta> afectadas = new ArrayList<Venta>();

    if (ventas.isEmpty()) {
      MessageUtils.showMessage("El grupo de ventas selccionadas no tiene saldo", "Pago con nota");
      return ventas;
    }

    // Obtener una lista de las posibles notas de credito para el pago para que el usuario
    // seleccione una
    final EventList<NotaDeCredito> notas =
        GlazedLists.eventList(getNotasManager().buscarNotasDeCreditoDisponibles(c));

    if (notas.isEmpty()) {
      MessageUtils.showMessage(
          MessageFormat.format(
              "El cliente {0} ({1})\n No tiene notas disponibles para usar como forma de pago",
              c.getNombre(), c.getClave()),
          "Notas disponibles");
      return afectadas;
    }
    final NotaDeCredito origen = Selectores.seleccionarNotaDeCredito(c, notas);
    // Procedemos con el pago
    if (origen != null) {
      final PagoConNota pago = getPagosFactory().crearPagoConNota(origen, ventas);
      final PagoFormModel model = new DefaultPagoFormModelImpl(pago);
      final PagoConNotaForm form = new PagoConNotaForm(model);
      form.open();
      if (!form.hasBeenCanceled()) {
        try {
          getPagosManager().salvarGrupoDePagos(pago);
          final List<Venta> ventasResultantes = PagosUtils.extraerVentas(pago);
          for (Venta vv : ventasResultantes) {
            getVentasManager().refresh(vv);
          }
          afectadas.addAll(ventasResultantes);
          completar(pago);
        } catch (Exception e) {
          MessageUtils.showError("Error al salvar pago", e);
        }
      }
    }
    return afectadas;
  }
Example #11
0
 private JComponent buildProveedorControl(final ValueModel vm) {
   if (model.getValue("proveedor") == null) {
     final JComboBox box = new JComboBox();
     final EventList source =
         GlazedLists.eventList(ServiceLocator2.getProveedorManager().getAll());
     final TextFilterator filterator =
         GlazedLists.textFilterator(new String[] {"clave", "nombre", "rfc"});
     AutoCompleteSupport support = AutoCompleteSupport.install(box, source, filterator);
     support.setFilterMode(TextMatcherEditor.CONTAINS);
     support.setStrict(false);
     final EventComboBoxModel model = (EventComboBoxModel) box.getModel();
     model.addListDataListener(new Bindings.WeakListDataListener(vm));
     box.setSelectedItem(vm.getValue());
     return box;
   } else {
     String prov = ((Proveedor) vm.getValue()).getNombreRazon();
     JLabel label = new JLabel(prov);
     return label;
   }
 }
    @SuppressWarnings("unchecked")
    public BodyLayerStack(
        List<T> values,
        IColumnPropertyAccessor<T> columnPropertyAccessor,
        TreeList.Format<T> treeFormat) {
      // wrapping of the list to show into GlazedLists
      // see http://publicobject.com/glazedlists/ for further information
      EventList<T> eventList = GlazedLists.eventList(values);
      TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);

      // use the SortedList constructor with 'null' for the Comparator because the Comparator
      // will be set by configuration
      SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
      // wrap the SortedList with the TreeList
      this.treeList = new TreeList<T>(sortedList, treeFormat, TreeList.NODES_START_EXPANDED);

      this.bodyDataProvider = new GlazedListsDataProvider<T>(treeList, columnPropertyAccessor);
      DataLayer bodyDataLayer = new DataLayer(this.bodyDataProvider);

      // simply apply labels for every column by index
      bodyDataLayer.setConfigLabelAccumulator(new ColumnLabelAccumulator());

      // layer for event handling of GlazedLists and PropertyChanges
      GlazedListsEventLayer<T> glazedListsEventLayer =
          new GlazedListsEventLayer<T>(bodyDataLayer, treeList);

      GlazedListTreeData<T> treeData =
          new GlazedListTreeData<T>(treeList) {
            @Override
            public String formatDataForDepth(int depth, T object) {
              if (object instanceof PersonWithAddress) {
                return ((PersonWithAddress) object).getLastName();
              }
              return null;
            }
          };
      ITreeRowModel<T> treeRowModel = new GlazedListTreeRowModel<T>(treeData);

      this.selectionLayer = new SelectionLayer(glazedListsEventLayer);

      TreeLayer treeLayer =
          new TreeLayer(selectionLayer, treeRowModel) {
            @Override
            public ICellPainter getCellPainter(
                int columnPosition,
                int rowPosition,
                ILayerCell cell,
                IConfigRegistry configRegistry) {
              ICellPainter painter =
                  super.getCellPainter(columnPosition, rowPosition, cell, configRegistry);
              // this is a little hack to get a padding between tree node icon and left border
              // the reason for this hack is that the TreeLayer internally wraps the registered
              // cell painter with the IndentedTreeImagePainter
              // so for backwards compatibility instead of adding it to the TreeLayer itself
              // we override getCellPainter() and wrap the created painter for the tree column again
              if (columnPosition == TREE_COLUMN_NUMBER) {
                painter = new PaddingDecorator(painter, 0, 0, 0, 2);
              }
              return painter;
            }
          };
      ViewportLayer viewportLayer = new ViewportLayer(treeLayer);

      setUnderlyingLayer(viewportLayer);
    }
/**
 * Example that demonstrates how to implement a NatTable instance that shows calculated values by
 * using the CalculatedValueCache. Also demonstrates the usage of the SummaryRow on updating the
 * NatTable.
 *
 * @author Dirk Fauth
 */
public class _803_CachedCalculatingGridExample extends AbstractNatExample {

  public static String COLUMN_ONE_LABEL = "ColumnOneLabel";
  public static String COLUMN_TWO_LABEL = "ColumnTwoLabel";
  public static String COLUMN_THREE_LABEL = "ColumnThreeLabel";
  public static String COLUMN_FOUR_LABEL = "ColumnFourLabel";
  public static String COLUMN_FIVE_LABEL = "ColumnFiveLabel";

  private EventList<NumberValues> valuesToShow =
      GlazedLists.eventList(new ArrayList<NumberValues>());

  public static void main(String[] args) throws Exception {
    StandaloneNatExampleRunner.run(new _803_CachedCalculatingGridExample());
  }

  /** @Override */
  @Override
  public String getDescription() {
    return "This example demonstrates how to create a NatTable that contains calculated values.\n"
        + "The first three columns are editable, while the last two columns contain the calculated values.\n"
        + "The values in column four and five will automatically update when committing the edited values.\n"
        + "This example also contains a summary row to show that it is even possible to update the summary "
        + "row in a editable grid. The value calculation is processed in background threads by using the "
        + "CalculatedValueCache in a specialised ListDataProvider.";
  }

  /* (non-Javadoc)
   * @see org.eclipse.nebula.widgets.nattable.examples.INatExample#createExampleControl(org.eclipse.swt.widgets.Composite)
   */
  @Override
  public Control createExampleControl(Composite parent) {
    Composite panel = new Composite(parent, SWT.NONE);
    panel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(panel);

    Composite gridPanel = new Composite(panel, SWT.NONE);
    gridPanel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(gridPanel);

    Composite buttonPanel = new Composite(panel, SWT.NONE);
    buttonPanel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(buttonPanel);

    // property names of the NumberValues class
    String[] propertyNames = {
      "columnOneNumber",
      "columnTwoNumber",
      "columnThreeNumber",
      "columnFourNumber",
      "columnFiveNumber"
    };

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("columnOneNumber", "100%");
    propertyToLabelMap.put("columnTwoNumber", "Value One");
    propertyToLabelMap.put("columnThreeNumber", "Value Two");
    propertyToLabelMap.put("columnFourNumber", "Sum");
    propertyToLabelMap.put("columnFiveNumber", "Percentage");

    valuesToShow.add(createNumberValues());
    valuesToShow.add(createNumberValues());

    ConfigRegistry configRegistry = new ConfigRegistry();

    CalculatingGridLayer gridLayer =
        new CalculatingGridLayer(valuesToShow, configRegistry, propertyNames, propertyToLabelMap);
    DataLayer bodyDataLayer = gridLayer.getBodyDataLayer();

    final ColumnOverrideLabelAccumulator columnLabelAccumulator =
        new ColumnOverrideLabelAccumulator(bodyDataLayer);
    bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
    registerColumnLabels(columnLabelAccumulator);

    final NatTable natTable = new NatTable(gridPanel, gridLayer, false);
    natTable.setConfigRegistry(configRegistry);
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(new CalculatingEditConfiguration());
    natTable.configure();
    GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);

    Button addRowButton = new Button(buttonPanel, SWT.PUSH);
    addRowButton.setText("add row");
    addRowButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            valuesToShow.add(createNumberValues());
          }
        });

    Button resetButton = new Button(buttonPanel, SWT.PUSH);
    resetButton.setText("reset");
    resetButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            valuesToShow.clear();
            valuesToShow.add(createNumberValues());
            valuesToShow.add(createNumberValues());
          }
        });

    return panel;
  }

  private void registerColumnLabels(ColumnOverrideLabelAccumulator columnLabelAccumulator) {
    columnLabelAccumulator.registerColumnOverrides(0, COLUMN_ONE_LABEL);
    columnLabelAccumulator.registerColumnOverrides(1, COLUMN_TWO_LABEL);
    columnLabelAccumulator.registerColumnOverrides(2, COLUMN_THREE_LABEL);
    columnLabelAccumulator.registerColumnOverrides(3, COLUMN_FOUR_LABEL);
    columnLabelAccumulator.registerColumnOverrides(4, COLUMN_FIVE_LABEL);
  }

  private NumberValues createNumberValues() {
    NumberValues nv = new NumberValues();
    nv.setColumnOneNumber(100); // the value which should be used as 100%
    nv.setColumnTwoNumber(20); // the value 1 for calculation
    nv.setColumnThreeNumber(30); // the value 2 for calculation
    // as column 4 and 5 should be calculated values, we don't set them to the NumberValues object
    return nv;
  }

  /**
   * The column accessor which is used for retrieving the basic data out of the model. The values
   * for the first three columns are returned directly. The values for column four and five are
   * calculated in the CachedValueCalculatingDataProvider by using the CalculatedValueCache.
   */
  class BasicDataColumnAccessor implements IColumnAccessor<NumberValues> {

    /* (non-Javadoc)
     * @see org.eclipse.nebula.widgets.nattable.data.IColumnAccessor#getDataValue(java.lang.Object, int)
     */
    @Override
    public Object getDataValue(NumberValues rowObject, int columnIndex) {
      switch (columnIndex) {
        case 0:
          return rowObject.getColumnOneNumber();
        case 1:
          return rowObject.getColumnTwoNumber();
        case 2:
          return rowObject.getColumnThreeNumber();
      }
      return null;
    }

    /* (non-Javadoc)
     * @see org.eclipse.nebula.widgets.nattable.data.IColumnAccessor#setDataValue(java.lang.Object, int, java.lang.Object)
     */
    @Override
    public void setDataValue(NumberValues rowObject, int columnIndex, Object newValue) {
      // because of the registered conversion, the new value has to be an Integer
      switch (columnIndex) {
        case 0:
          rowObject.setColumnOneNumber((Integer) newValue);
          break;
        case 1:
          rowObject.setColumnTwoNumber((Integer) newValue);
          break;
        case 2:
          rowObject.setColumnThreeNumber((Integer) newValue);
          break;
      }
    }

    /* (non-Javadoc)
     * @see org.eclipse.nebula.widgets.nattable.data.IColumnAccessor#getColumnCount()
     */
    @Override
    public int getColumnCount() {
      // this example will show exactly 5 columns
      return 5;
    }
  }

  /**
   * Specialised ListDataProvider that is using the CalculatedValueCache for background processing
   * of calculated column values.
   *
   * <p>As the updates after the calculation processing need to be fired via ILayer, the
   * CalculatedValueCache is created with no ILayer at construction time. But the DataLayer e.g.
   * needs to be set in order to make the automatic updates on data modifications work.
   */
  class CachedValueCalculatingDataProvider<T> extends GlazedListsDataProvider<T> {

    private CalculatedValueCache valueCache;

    public CachedValueCalculatingDataProvider(
        EventList<T> list, IColumnAccessor<T> columnAccessor) {
      super(list, columnAccessor);
      // create the CalculatedValueCache without layer reference, as the data provider is no layer
      this.valueCache = new CalculatedValueCache(null, true, true);
    }

    @Override
    public Object getDataValue(final int colIndex, final int rowIndex) {
      if (colIndex == 3) {
        Object result =
            this.valueCache.getCalculatedValue(
                colIndex,
                rowIndex,
                true,
                new ICalculator() {
                  @Override
                  public Object executeCalculation() {
                    // calculate the sum
                    int colTwo = (Integer) getDataValue(1, rowIndex);
                    int colThree = (Integer) getDataValue(2, rowIndex);
                    // add some delay
                    try {
                      Thread.sleep(500);
                    } catch (InterruptedException e) {
                    }
                    return colTwo + colThree;
                  }
                });

        return result == null ? 0 : result;
      } else if (colIndex == 4) {
        Object result =
            this.valueCache.getCalculatedValue(
                colIndex,
                rowIndex,
                true,
                new ICalculator() {
                  @Override
                  public Object executeCalculation() {
                    // calculate the percentage
                    int colOne = (Integer) getDataValue(0, rowIndex);
                    int colTwo = (Integer) getDataValue(1, rowIndex);
                    int colThree = (Integer) getDataValue(2, rowIndex);
                    // add some delay
                    try {
                      Thread.sleep(500);
                    } catch (InterruptedException e) {
                    }
                    return new Double(colTwo + colThree) / colOne;
                  }
                });

        return result == null ? new Double(0) : result;
      }

      return super.getDataValue(colIndex, rowIndex);
    }

    public void setCacheEventLayer(ILayer layer) {
      this.valueCache.setLayer(layer);
    }
  }

  /**
   * The body layer stack for the {@link _803_CachedCalculatingGridExample}. Consists of
   *
   * <ol>
   *   <li>ViewportLayer
   *   <li>SelectionLayer
   *   <li>ColumnHideShowLayer
   *   <li>ColumnReorderLayer
   *   <li>SummaryRowLayer
   *   <li>GlazedListsEventLayer
   *   <li>DataLayer
   * </ol>
   */
  class CalculatingBodyLayerStack extends AbstractLayerTransform {

    private final DataLayer bodyDataLayer;
    private final GlazedListsEventLayer<NumberValues> glazedListsEventLayer;
    private final SummaryRowLayer summaryRowLayer;
    private final ColumnReorderLayer columnReorderLayer;
    private final ColumnHideShowLayer columnHideShowLayer;
    private final SelectionLayer selectionLayer;
    private final ViewportLayer viewportLayer;

    public CalculatingBodyLayerStack(
        EventList<NumberValues> valuesToShow, ConfigRegistry configRegistry) {
      final CachedValueCalculatingDataProvider<NumberValues> dataProvider =
          new CachedValueCalculatingDataProvider<NumberValues>(
              valuesToShow, new BasicDataColumnAccessor());
      bodyDataLayer = new DataLayer(dataProvider);
      // adding this listener will trigger updates on data changes
      bodyDataLayer.addLayerListener(
          new ILayerListener() {
            @Override
            public void handleLayerEvent(ILayerEvent event) {
              if (event instanceof IVisualChangeEvent) {
                dataProvider.valueCache.clearCache();
              }
            }
          });
      // register a layer listener to ensure the value cache gets disposed
      bodyDataLayer.registerCommandHandler(
          new ILayerCommandHandler<DisposeResourcesCommand>() {

            @Override
            public boolean doCommand(ILayer targetLayer, DisposeResourcesCommand command) {
              dataProvider.valueCache.dispose();
              return false;
            }

            @Override
            public Class<DisposeResourcesCommand> getCommandClass() {
              return DisposeResourcesCommand.class;
            }
          });

      // connect the DataLayer with the data provider so the value cache knows how to fire updates
      dataProvider.setCacheEventLayer(bodyDataLayer);

      glazedListsEventLayer = new GlazedListsEventLayer<NumberValues>(bodyDataLayer, valuesToShow);
      summaryRowLayer = new SummaryRowLayer(glazedListsEventLayer, configRegistry, false);
      summaryRowLayer.addConfiguration(
          new CalculatingSummaryRowConfiguration(bodyDataLayer.getDataProvider()));
      columnReorderLayer = new ColumnReorderLayer(summaryRowLayer);
      columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
      selectionLayer = new SelectionLayer(columnHideShowLayer);
      viewportLayer = new ViewportLayer(selectionLayer);
      setUnderlyingLayer(viewportLayer);

      registerCommandHandler(new CopyDataCommandHandler(selectionLayer));
    }

    public DataLayer getDataLayer() {
      return this.bodyDataLayer;
    }

    public SelectionLayer getSelectionLayer() {
      return selectionLayer;
    }
  }

  /** The {@link GridLayer} used by the {@link _803_CachedCalculatingGridExample}. */
  class CalculatingGridLayer extends GridLayer {

    public CalculatingGridLayer(
        EventList<NumberValues> valuesToShow,
        ConfigRegistry configRegistry,
        final String[] propertyNames,
        Map<String, String> propertyToLabelMap) {
      super(true);
      init(valuesToShow, configRegistry, propertyNames, propertyToLabelMap);
    }

    private void init(
        EventList<NumberValues> valuesToShow,
        ConfigRegistry configRegistry,
        final String[] propertyNames,
        Map<String, String> propertyToLabelMap) {
      // Body
      CalculatingBodyLayerStack bodyLayer =
          new CalculatingBodyLayerStack(valuesToShow, configRegistry);

      SelectionLayer selectionLayer = bodyLayer.getSelectionLayer();

      // Column header
      IDataProvider columnHeaderDataProvider =
          new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
      ILayer columnHeaderLayer =
          new ColumnHeaderLayer(
              new DefaultColumnHeaderDataLayer(columnHeaderDataProvider),
              bodyLayer,
              selectionLayer);

      // Row header
      IDataProvider rowHeaderDataProvider =
          new DefaultSummaryRowHeaderDataProvider(
              bodyLayer.getDataLayer().getDataProvider(), "\u2211");
      ILayer rowHeaderLayer =
          new RowHeaderLayer(
              new DefaultRowHeaderDataLayer(rowHeaderDataProvider), bodyLayer, selectionLayer);

      // Corner
      ILayer cornerLayer =
          new CornerLayer(
              new DataLayer(
                  new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)),
              rowHeaderLayer,
              columnHeaderLayer);

      setBodyLayer(bodyLayer);
      setColumnHeaderLayer(columnHeaderLayer);
      setRowHeaderLayer(rowHeaderLayer);
      setCornerLayer(cornerLayer);
    }

    public DataLayer getBodyDataLayer() {
      return ((CalculatingBodyLayerStack) getBodyLayer()).getDataLayer();
    }
  }

  /** Configuration for enabling and configuring edit behaviour. */
  class CalculatingEditConfiguration extends AbstractRegistryConfiguration {

    @Override
    public void configureRegistry(IConfigRegistry configRegistry) {
      configRegistry.registerConfigAttribute(
          EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.ALWAYS_EDITABLE);
      configRegistry.registerConfigAttribute(
          EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.NEVER_EDITABLE,
          DisplayMode.EDIT, _803_CachedCalculatingGridExample.COLUMN_FOUR_LABEL);
      configRegistry.registerConfigAttribute(
          EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.NEVER_EDITABLE,
          DisplayMode.EDIT, _803_CachedCalculatingGridExample.COLUMN_FIVE_LABEL);
      // configure the summary row to be not editable
      configRegistry.registerConfigAttribute(
          EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.NEVER_EDITABLE,
          DisplayMode.EDIT, SummaryRowLayer.DEFAULT_SUMMARY_ROW_CONFIG_LABEL);

      configRegistry.registerConfigAttribute(
          CellConfigAttributes.DISPLAY_CONVERTER,
          new DefaultIntegerDisplayConverter(),
          DisplayMode.NORMAL);
      configRegistry.registerConfigAttribute(
          CellConfigAttributes.DISPLAY_CONVERTER,
          new DefaultIntegerDisplayConverter(),
          DisplayMode.EDIT);

      configRegistry.registerConfigAttribute(
          CellConfigAttributes.DISPLAY_CONVERTER,
          new PercentageDisplayConverter(),
          DisplayMode.NORMAL,
          _803_CachedCalculatingGridExample.COLUMN_FIVE_LABEL);

      configRegistry.registerConfigAttribute(
          CellConfigAttributes.DISPLAY_CONVERTER,
          new SummaryDisplayConverter(new DefaultIntegerDisplayConverter()),
          DisplayMode.NORMAL,
          SummaryRowLayer.DEFAULT_SUMMARY_ROW_CONFIG_LABEL);

      configRegistry.registerConfigAttribute(
          CellConfigAttributes.DISPLAY_CONVERTER,
          new SummaryDisplayConverter(new PercentageDisplayConverter()),
          DisplayMode.NORMAL,
          SummaryRowLayer.DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX + 4);
    }
  }

  class CalculatingSummaryRowConfiguration extends DefaultSummaryRowConfiguration {

    private final IDataProvider dataProvider;

    public CalculatingSummaryRowConfiguration(IDataProvider dataProvider) {
      this.dataProvider = dataProvider;
      summaryRowBgColor = GUIHelper.COLOR_BLUE;
      summaryRowFgColor = GUIHelper.COLOR_WHITE;
    }

    @Override
    public void addSummaryProviderConfig(IConfigRegistry configRegistry) {
      // Labels are applied to the summary row and cells by default to make configuration easier.
      // See the Javadoc for the SummaryRowLayer

      // Default summary provider
      configRegistry.registerConfigAttribute(
          SummaryRowConfigAttributes.SUMMARY_PROVIDER,
          new SummationSummaryProvider(dataProvider),
          DisplayMode.NORMAL,
          SummaryRowLayer.DEFAULT_SUMMARY_ROW_CONFIG_LABEL);

      // Average summary provider for column index 2
      configRegistry.registerConfigAttribute(
          SummaryRowConfigAttributes.SUMMARY_PROVIDER,
          new AverageSummaryProvider(),
          DisplayMode.NORMAL,
          SummaryRowLayer.DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX + 4);
    }

    /** Custom summary provider which averages out the contents of the column */
    class AverageSummaryProvider implements ISummaryProvider {
      @Override
      public Object summarize(int columnIndex) {
        double total = 0;
        int rowCount = dataProvider.getRowCount();

        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
          Object dataValue = dataProvider.getDataValue(columnIndex, rowIndex);
          total = total + Double.parseDouble(dataValue.toString());
        }
        return total / rowCount;
      }
    }
  }
}
  @Override
  public Control createExampleControl(Composite parent) {
    // property names of the Person class
    String[] propertyNames = {"firstName", "lastName", "gender", "married", "birthday"};

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("firstName", "Firstname");
    propertyToLabelMap.put("lastName", "Lastname");
    propertyToLabelMap.put("gender", "Gender");
    propertyToLabelMap.put("married", "Married");
    propertyToLabelMap.put("birthday", "Birthday");

    // build the body layer stack
    // Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
    // setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
    // directly as body layer is also working.

    // first wrap the base list in a GlazedLists EventList and a FilterList so it is possible to
    // filter
    EventList<Person> eventList = GlazedLists.eventList(PersonService.getPersons(10));
    FilterList<Person> filterList = new FilterList<Person>(eventList);

    // use the GlazedListsDataProvider for some performance tweaks
    final IRowDataProvider<Person> bodyDataProvider =
        new GlazedListsDataProvider<Person>(
            filterList, new ReflectiveColumnPropertyAccessor<Person>(propertyNames));
    // create the IRowIdAccessor that is necessary for row hide/show
    final IRowIdAccessor<Person> rowIdAccessor =
        new IRowIdAccessor<Person>() {
          @Override
          public Serializable getRowId(Person rowObject) {
            return rowObject.getId();
          }
        };

    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);

    // add a DetailGlazedListsEventLayer event layer that is responsible for updating the grid on
    // list changes
    DetailGlazedListsEventLayer<Person> glazedListsEventLayer =
        new DetailGlazedListsEventLayer<Person>(bodyDataLayer, filterList);

    GlazedListsRowHideShowLayer<Person> rowHideShowLayer =
        new GlazedListsRowHideShowLayer<Person>(
            glazedListsEventLayer, bodyDataProvider, rowIdAccessor, filterList);

    SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
    ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

    // build the column header layer
    IDataProvider columnHeaderDataProvider =
        new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    ILayer columnHeaderLayer =
        new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);

    // build the row header layer
    IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
    DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);

    // build the corner layer
    IDataProvider cornerDataProvider =
        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);

    // build the grid layer
    GridLayer gridLayer =
        new GridLayer(viewportLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);

    // turn the auto configuration off as we want to add our header menu configuration
    NatTable natTable = new NatTable(parent, gridLayer, false);

    // as the autoconfiguration of the NatTable is turned off, we have to add the
    // DefaultNatTableStyleConfiguration manually
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());

    // add the header menu configuration for adding the column header menu with hide/show actions
    natTable.addConfiguration(
        new AbstractHeaderMenuConfiguration(natTable) {

          @Override
          protected PopupMenuBuilder createRowHeaderMenu(NatTable natTable) {
            return new PopupMenuBuilder(natTable).withHideRowMenuItem().withShowAllRowsMenuItem();
          }

          @Override
          protected PopupMenuBuilder createCornerMenu(NatTable natTable) {
            return super.createCornerMenu(natTable)
                .withShowAllRowsMenuItem()
                .withStateManagerMenuItemProvider();
          }
        });
    natTable.configure();

    natTable.registerCommandHandler(new DisplayPersistenceDialogCommandHandler(natTable));

    return natTable;
  }
  @Override
  public Control createExampleControl(Composite parent) {
    IConfigRegistry configRegistry = new ConfigRegistry();

    // Underlying data source
    EventList<RowDataFixture> eventList = GlazedLists.eventList(RowDataListFixture.getList(200));
    FilterList<RowDataFixture> filterList = new FilterList<RowDataFixture>(eventList);
    String[] propertyNames = RowDataListFixture.getPropertyNames();
    Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();

    // Body
    IColumnPropertyAccessor<RowDataFixture> columnPropertyAccessor =
        new ReflectiveColumnPropertyAccessor<RowDataFixture>(propertyNames);
    ListDataProvider<RowDataFixture> bodyDataProvider =
        new ListDataProvider<RowDataFixture>(filterList, columnPropertyAccessor);
    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
    ColumnGroupBodyLayerStack bodyLayer =
        new ColumnGroupBodyLayerStack(bodyDataLayer, columnGroupModel);

    ColumnOverrideLabelAccumulator bodyLabelAccumulator =
        new ColumnOverrideLabelAccumulator(bodyDataLayer);
    bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);

    bodyLabelAccumulator.registerColumnOverrides(
        RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
        "PRICING_TYPE_PROP_NAME");

    // Column header
    IDataProvider columnHeaderDataProvider =
        new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
    DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    columnHeaderLayer =
        new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());
    ColumnGroupHeaderLayer columnGroupHeaderLayer =
        new ColumnGroupHeaderLayer(
            columnHeaderLayer, bodyLayer.getSelectionLayer(), columnGroupModel);

    columnGroupHeaderLayer.addColumnsIndexesToGroup("Group 1", 1, 2);

    // calculate the height of the column header area dependent if column groups exist or not
    columnGroupHeaderLayer.setCalculateHeight(true);

    //	Note: The column header layer is wrapped in a filter row composite.
    //	This plugs in the filter row functionality
    final FilterRowHeaderComposite<RowDataFixture> filterRowHeaderLayer =
        new FilterRowHeaderComposite<RowDataFixture>(
            new DefaultGlazedListsFilterStrategy<RowDataFixture>(
                filterList, columnPropertyAccessor, configRegistry),
            columnGroupHeaderLayer,
            columnHeaderDataProvider,
            configRegistry);

    filterRowHeaderLayer.setFilterRowVisible(false);

    ColumnOverrideLabelAccumulator labelAccumulator =
        new ColumnOverrideLabelAccumulator(columnHeaderDataLayer);
    columnHeaderDataLayer.setConfigLabelAccumulator(labelAccumulator);

    // Register labels
    labelAccumulator.registerColumnOverrides(
        RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.RATING_PROP_NAME),
        "CUSTOM_COMPARATOR_LABEL");

    // Row header

    final DefaultRowHeaderDataProvider rowHeaderDataProvider =
        new DefaultRowHeaderDataProvider(bodyDataProvider);
    DefaultRowHeaderDataLayer rowHeaderDataLayer =
        new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
    ILayer rowHeaderLayer =
        new RowHeaderLayer(rowHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());

    // Corner

    final DefaultCornerDataProvider cornerDataProvider =
        new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
    DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
    ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, filterRowHeaderLayer);

    // Grid
    GridLayer gridLayer =
        new GridLayer(bodyLayer, filterRowHeaderLayer, rowHeaderLayer, cornerLayer);

    NatTable natTable = new NatTable(parent, gridLayer, false);

    // Register create column group command handler

    // Register column chooser
    DisplayColumnChooserCommandHandler columnChooserCommandHandler =
        new DisplayColumnChooserCommandHandler(
            bodyLayer.getSelectionLayer(),
            bodyLayer.getColumnHideShowLayer(),
            columnHeaderLayer,
            columnHeaderDataLayer,
            columnGroupHeaderLayer,
            columnGroupModel);
    bodyLayer.registerCommandHandler(columnChooserCommandHandler);

    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(
        new HeaderMenuConfiguration(natTable) {
          @Override
          protected PopupMenuBuilder createColumnHeaderMenu(NatTable natTable) {
            return super.createColumnHeaderMenu(natTable).withColumnChooserMenuItem();
          }
        });
    natTable.addConfiguration(
        new AbstractRegistryConfiguration() {
          @Override
          public void configureRegistry(IConfigRegistry configRegistry) {
            configRegistry.registerConfigAttribute(
                ExportConfigAttributes.EXPORTER, new HSSFExcelExporter());
          }
        });
    natTable.addConfiguration(new FilterRowCustomConfiguration());

    natTable.setConfigRegistry(configRegistry);
    natTable.configure();

    // add button
    Button button = new Button(parent, SWT.NONE);
    button.setText("Switch FilterRow visibility");
    button.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            filterRowHeaderLayer.setFilterRowVisible(!filterRowHeaderLayer.isFilterRowVisible());
          }
        });

    return natTable;
  }
/**
 * Example that demonstrates how to implement a NatTable instance that shows calculated values. Also
 * demonstrates the usage of the SummaryRow on updating the NatTable.
 *
 * @author Dirk Fauth
 */
public class CalculatingGridExample extends AbstractNatExample {

  public static String COLUMN_ONE_LABEL = "ColumnOneLabel";
  public static String COLUMN_TWO_LABEL = "ColumnTwoLabel";
  public static String COLUMN_THREE_LABEL = "ColumnThreeLabel";
  public static String COLUMN_FOUR_LABEL = "ColumnFourLabel";
  public static String COLUMN_FIVE_LABEL = "ColumnFiveLabel";

  private EventList<NumberValues> valuesToShow =
      GlazedLists.eventList(new ArrayList<NumberValues>());

  public static void main(String[] args) throws Exception {
    StandaloneNatExampleRunner.run(new CalculatingGridExample());
  }

  /** @Override */
  public String getDescription() {
    return "Demonstrates how to implement a editable grid with calculated column values.\n"
        + "Also adds the SummaryRow to demonstrate how the SummaryRow updates on changes "
        + "within the grid.";
  }

  /* (non-Javadoc)
   * @see org.eclipse.nebula.widgets.nattable.examples.INatExample#createExampleControl(org.eclipse.swt.widgets.Composite)
   */
  public Control createExampleControl(Composite parent) {
    Composite panel = new Composite(parent, SWT.NONE);
    panel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(panel);

    Composite gridPanel = new Composite(panel, SWT.NONE);
    gridPanel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(gridPanel);

    Composite buttonPanel = new Composite(panel, SWT.NONE);
    buttonPanel.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(buttonPanel);

    // property names of the NumberValues class
    String[] propertyNames = {
      "columnOneNumber",
      "columnTwoNumber",
      "columnThreeNumber",
      "columnFourNumber",
      "columnFiveNumber"
    };

    // mapping from property to label, needed for column header labels
    Map<String, String> propertyToLabelMap = new HashMap<String, String>();
    propertyToLabelMap.put("columnOneNumber", "100%");
    propertyToLabelMap.put("columnTwoNumber", "Value One");
    propertyToLabelMap.put("columnThreeNumber", "Value Two");
    propertyToLabelMap.put("columnFourNumber", "Sum");
    propertyToLabelMap.put("columnFiveNumber", "Percentage");

    valuesToShow.add(createNumberValues());
    valuesToShow.add(createNumberValues());

    ConfigRegistry configRegistry = new ConfigRegistry();

    CalculatingGridLayer gridLayer =
        new CalculatingGridLayer(valuesToShow, configRegistry, propertyNames, propertyToLabelMap);
    DataLayer bodyDataLayer = (DataLayer) gridLayer.getBodyDataLayer();

    final ColumnOverrideLabelAccumulator columnLabelAccumulator =
        new ColumnOverrideLabelAccumulator(bodyDataLayer);
    bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
    registerColumnLabels(columnLabelAccumulator);

    final NatTable natTable = new NatTable(gridPanel, gridLayer, false);
    natTable.setConfigRegistry(configRegistry);
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
    natTable.addConfiguration(new CalculatingEditConfiguration());
    natTable.configure();
    GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);

    Button addRowButton = new Button(buttonPanel, SWT.PUSH);
    addRowButton.setText("add row");
    addRowButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            valuesToShow.add(createNumberValues());
          }
        });

    Button resetButton = new Button(buttonPanel, SWT.PUSH);
    resetButton.setText("reset");
    resetButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            valuesToShow.clear();
            valuesToShow.add(createNumberValues());
            valuesToShow.add(createNumberValues());
          }
        });

    return panel;
  }

  private void registerColumnLabels(ColumnOverrideLabelAccumulator columnLabelAccumulator) {
    columnLabelAccumulator.registerColumnOverrides(0, COLUMN_ONE_LABEL);
    columnLabelAccumulator.registerColumnOverrides(1, COLUMN_TWO_LABEL);
    columnLabelAccumulator.registerColumnOverrides(2, COLUMN_THREE_LABEL);
    columnLabelAccumulator.registerColumnOverrides(3, COLUMN_FOUR_LABEL);
    columnLabelAccumulator.registerColumnOverrides(4, COLUMN_FIVE_LABEL);
  }

  private NumberValues createNumberValues() {
    NumberValues nv = new NumberValues();
    nv.setColumnOneNumber(100); // the value which should be used as 100%
    nv.setColumnTwoNumber(20); // the value 1 for calculation
    nv.setColumnThreeNumber(30); // the value 2 for calculation
    // as column 4 and 5 should be calculated values, we don't set them to the NumberValues object
    return nv;
  }
}