/** * 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); }
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); }
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; }
@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(); }
/** * 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; }
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; } }