51 |
51 |
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommandHandler;
|
52 |
52 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
|
53 |
53 |
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
|
|
54 |
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
|
54 |
55 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
|
55 |
56 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
|
56 |
57 |
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
|
|
58 |
import org.eclipse.nebula.widgets.nattable.grid.data.FixedSummaryRowHeaderLayer;
|
57 |
59 |
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
|
58 |
60 |
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
|
|
61 |
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
|
59 |
62 |
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
|
60 |
|
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
|
61 |
63 |
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
|
62 |
64 |
import org.eclipse.nebula.widgets.nattable.hideshow.RowHideShowLayer;
|
|
65 |
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
|
63 |
66 |
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
|
64 |
67 |
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
|
65 |
68 |
import org.eclipse.nebula.widgets.nattable.layer.ILayerListener;
|
... | ... | |
78 |
81 |
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
|
79 |
82 |
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
|
80 |
83 |
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
|
|
84 |
import org.eclipse.nebula.widgets.nattable.summaryrow.FixedSummaryRowLayer;
|
|
85 |
import org.eclipse.nebula.widgets.nattable.summaryrow.SummaryRowLayer;
|
81 |
86 |
import org.eclipse.nebula.widgets.nattable.ui.menu.AbstractHeaderMenuConfiguration;
|
|
87 |
import org.eclipse.nebula.widgets.nattable.ui.menu.DebugMenuConfiguration;
|
82 |
88 |
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
|
83 |
89 |
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
|
84 |
90 |
import org.eclipse.swt.SWT;
|
... | ... | |
184 |
190 |
List<Feature> features = new ArrayList<>(tree.getDistinctFeatures());
|
185 |
191 |
Collections.sort(features);
|
186 |
192 |
|
187 |
|
|
188 |
193 |
descriptions = GlazedLists.eventList(getDescriptions(workingSet));
|
189 |
194 |
SortedList<RowWrapper> sortedList = new SortedList<>(descriptions, null);
|
190 |
195 |
|
|
196 |
ConfigRegistry configRegistry = new ConfigRegistry();
|
|
197 |
|
191 |
198 |
/**
|
192 |
199 |
* data provider
|
193 |
200 |
*/
|
... | ... | |
196 |
203 |
|
197 |
204 |
/**
|
198 |
205 |
* BODY layer
|
|
206 |
*
|
|
207 |
*
|
|
208 |
|
|
209 |
CompositeLayer
|
|
210 |
- (top) SummaryRowLayer
|
|
211 |
- (bottom) ViewportLayer
|
|
212 |
|
|
213 |
^
|
|
214 |
ViewportLayer
|
|
215 |
|
|
216 |
^
|
|
217 |
SelectionLayer
|
|
218 |
|
|
219 |
^
|
|
220 |
RowHideShowLayer
|
|
221 |
|
|
222 |
^
|
|
223 |
ColumnHideShowLayer
|
|
224 |
|
|
225 |
^
|
|
226 |
ColumnReorderLayer
|
|
227 |
|
|
228 |
^
|
|
229 |
RowReorderLayer
|
|
230 |
|
|
231 |
^
|
|
232 |
DataLayer
|
|
233 |
|
|
234 |
*
|
|
235 |
|
199 |
236 |
*/
|
200 |
237 |
DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
|
201 |
238 |
|
202 |
239 |
//register labels for columns
|
203 |
|
final ColumnOverrideLabelAccumulator columnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
|
204 |
|
bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
|
|
240 |
ColumnOverrideLabelAccumulator bodyColumnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
|
|
241 |
bodyDataLayer.setConfigLabelAccumulator(bodyColumnLabelAccumulator);
|
205 |
242 |
propertyToLabelMap.put(TAXON_COLUMN, "Taxon");
|
206 |
|
columnLabelAccumulator.registerColumnOverrides(0, TAXON_COLUMN);
|
|
243 |
bodyColumnLabelAccumulator.registerColumnOverrides(0, TAXON_COLUMN);
|
207 |
244 |
propertyToLabelMap.put(COLLECTOR_COLUMN, "Collector + No");
|
208 |
|
columnLabelAccumulator.registerColumnOverrides(1, COLLECTOR_COLUMN);
|
|
245 |
bodyColumnLabelAccumulator.registerColumnOverrides(1, COLLECTOR_COLUMN);
|
209 |
246 |
propertyToLabelMap.put(IDENTIFIER_COLUMN, "Identifier");
|
210 |
|
columnLabelAccumulator.registerColumnOverrides(2, IDENTIFIER_COLUMN);
|
|
247 |
bodyColumnLabelAccumulator.registerColumnOverrides(2, IDENTIFIER_COLUMN);
|
211 |
248 |
propertyToLabelMap.put(COUNTRY_COLUMN, "Country");
|
212 |
|
columnLabelAccumulator.registerColumnOverrides(3, COUNTRY_COLUMN);
|
|
249 |
bodyColumnLabelAccumulator.registerColumnOverrides(3, COUNTRY_COLUMN);
|
213 |
250 |
for(int i=0;i<features.size();i++){
|
214 |
251 |
Feature feature = features.get(i);
|
215 |
|
initLabels(columnLabelAccumulator, i, feature);
|
|
252 |
initLabels(bodyColumnLabelAccumulator, i, feature);
|
216 |
253 |
}
|
217 |
254 |
|
218 |
255 |
GlazedListsEventLayer<RowWrapper> eventLayer = new GlazedListsEventLayer<>(bodyDataLayer, sortedList);
|
... | ... | |
224 |
261 |
SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
|
225 |
262 |
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
|
226 |
263 |
|
|
264 |
|
|
265 |
// create a standalone FixedSummaryRowLayer
|
|
266 |
// since the summary row should be fixed at the top of the body
|
|
267 |
// region the horizontal dependency of the FixedSummaryRowLayer
|
|
268 |
// is the ViewportLayer
|
|
269 |
FixedSummaryRowLayer summaryRowLayer =
|
|
270 |
new FixedSummaryRowLayer(bodyDataLayer, viewportLayer, configRegistry, false);
|
|
271 |
//regoster labels with summary prefix for summary layer
|
|
272 |
ColumnOverrideLabelAccumulator summaryColumnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
|
|
273 |
summaryRowLayer.setConfigLabelAccumulator(summaryColumnLabelAccumulator);
|
|
274 |
for(int i=0;i<features.size();i++){
|
|
275 |
Feature feature = features.get(i);
|
|
276 |
summaryColumnLabelAccumulator.registerColumnOverrides(
|
|
277 |
i+LEADING_COLUMN_COUNT,
|
|
278 |
SummaryRowLayer.DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX+MatrixUtility.getProperty(feature));
|
|
279 |
}
|
|
280 |
// because the horizontal dependency is the ViewportLayer
|
|
281 |
// we need to set the composite dependency to false
|
|
282 |
summaryRowLayer.setHorizontalCompositeDependency(false);
|
|
283 |
|
|
284 |
CompositeLayer composite = new CompositeLayer(1, 2);
|
|
285 |
composite.setChildLayer("SUMMARY", summaryRowLayer, 0, 0);
|
|
286 |
composite.setChildLayer(GridRegion.BODY, viewportLayer, 0, 1);
|
|
287 |
|
|
288 |
|
|
289 |
|
|
290 |
|
227 |
291 |
/**
|
228 |
292 |
* column header layer
|
229 |
293 |
*/
|
... | ... | |
232 |
296 |
DataLayer columnHeaderDataLayer = new DataLayer(columnHeaderDataProvider);
|
233 |
297 |
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);
|
234 |
298 |
|
235 |
|
ConfigRegistry configRegistry = new ConfigRegistry();
|
236 |
|
|
237 |
299 |
// add the SortHeaderLayer to the column header layer stack
|
238 |
300 |
// as we use GlazedLists, we use the GlazedListsSortModel which
|
239 |
301 |
// delegates the sorting to the SortedList
|
... | ... | |
250 |
312 |
* row header layer
|
251 |
313 |
*/
|
252 |
314 |
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
|
253 |
|
DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider, 40, 20);
|
254 |
|
ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);
|
|
315 |
DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
|
|
316 |
FixedSummaryRowHeaderLayer fixedSummaryRowHeaderLayer = new FixedSummaryRowHeaderLayer(rowHeaderDataLayer,
|
|
317 |
composite, selectionLayer);
|
|
318 |
fixedSummaryRowHeaderLayer.setSummaryRowLabel("\u2211");
|
255 |
319 |
|
256 |
320 |
|
257 |
321 |
/**
|
... | ... | |
259 |
323 |
*/
|
260 |
324 |
ILayer cornerLayer = new CornerLayer(
|
261 |
325 |
new DataLayer(new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)),
|
262 |
|
rowHeaderLayer, sortHeaderLayer);
|
|
326 |
fixedSummaryRowHeaderLayer, sortHeaderLayer);
|
263 |
327 |
|
264 |
328 |
|
265 |
329 |
/**
|
266 |
330 |
* GRID layer (composition of all other layers)
|
267 |
331 |
*/
|
268 |
|
GridLayer gridLayer = new GridLayer(viewportLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer);
|
|
332 |
GridLayer gridLayer = new GridLayer(composite, sortHeaderLayer, fixedSummaryRowHeaderLayer, cornerLayer);
|
|
333 |
|
269 |
334 |
|
270 |
335 |
|
271 |
336 |
natTable = new NatTable(parent, gridLayer, false);
|
... | ... | |
284 |
349 |
// to sort on a single click
|
285 |
350 |
natTable.addConfiguration(new SingleClickSortConfiguration());
|
286 |
351 |
|
|
352 |
//FIXME: this is for DEBUG ONLY
|
|
353 |
natTable.addConfiguration(new DebugMenuConfiguration(natTable));
|
|
354 |
|
287 |
355 |
// add the header menu configuration for adding the column header menu
|
288 |
356 |
// with hide/show actions
|
289 |
357 |
natTable.addConfiguration(new AbstractHeaderMenuConfiguration(natTable) {
|
... | ... | |
310 |
378 |
}
|
311 |
379 |
});
|
312 |
380 |
|
313 |
|
// add custom configuration for data conversion and add column labels
|
|
381 |
// add custom configuration for data conversion and add column labels to viewport layer
|
314 |
382 |
viewportLayer.addConfiguration(new AbstractRegistryConfiguration() {
|
315 |
383 |
@Override
|
316 |
384 |
public void configureRegistry(IConfigRegistry configRegistry) {
|
... | ... | |
340 |
408 |
|
341 |
409 |
});
|
342 |
410 |
|
|
411 |
//register aggregation configuration for each feature
|
|
412 |
features.forEach(feature->summaryRowLayer.addConfiguration(new AggregationConfiguration(bodyDataProvider, feature)));
|
|
413 |
|
343 |
414 |
// add the ExportCommandHandler to the ViewportLayer in order to make
|
344 |
415 |
// exporting work
|
345 |
416 |
viewportLayer.registerCommandHandler(new ExportCommandHandler(viewportLayer));
|
... | ... | |
354 |
425 |
StructuredSelection selection = new StructuredSelection();
|
355 |
426 |
if(selectedCells.size()==1){
|
356 |
427 |
ILayerCell cell = selectedCells.iterator().next();
|
357 |
|
selection = new StructuredSelection(cell.getDataValue());
|
|
428 |
Object dataValue = cell.getDataValue();
|
|
429 |
if(dataValue!=null){
|
|
430 |
selection = new StructuredSelection(dataValue);
|
|
431 |
}
|
358 |
432 |
}
|
359 |
433 |
selService.setSelection(selection);
|
360 |
434 |
}
|
... | ... | |
468 |
542 |
private void initLabels(final ColumnOverrideLabelAccumulator columnLabelAccumulator,
|
469 |
543 |
int index, Feature feature) {
|
470 |
544 |
|
471 |
|
columnLabelAccumulator.registerColumnOverrides(index+LEADING_COLUMN_COUNT, getProperty(feature));
|
|
545 |
columnLabelAccumulator.registerColumnOverrides(index+LEADING_COLUMN_COUNT, MatrixUtility.getProperty(feature));
|
472 |
546 |
indexToFeatureMap.put(index+LEADING_COLUMN_COUNT, feature);
|
473 |
547 |
|
474 |
548 |
String featureLabel = feature.getLabel();
|
... | ... | |
493 |
567 |
EditConfigAttributes.CELL_EDITABLE_RULE,
|
494 |
568 |
IEditableRule.ALWAYS_EDITABLE,
|
495 |
569 |
DisplayMode.EDIT,
|
496 |
|
getProperty(feature)
|
|
570 |
MatrixUtility.getProperty(feature)
|
497 |
571 |
);
|
498 |
572 |
if(feature.isSupportsQuantitativeData()){
|
499 |
573 |
//add display converter for string representation
|
... | ... | |
501 |
575 |
CellConfigAttributes.DISPLAY_CONVERTER,
|
502 |
576 |
new QuantitativeDataDisplayConverter(),
|
503 |
577 |
DisplayMode.NORMAL,
|
504 |
|
getProperty(feature));
|
|
578 |
MatrixUtility.getProperty(feature));
|
505 |
579 |
//register quantitative editor
|
506 |
580 |
configRegistry.registerConfigAttribute(
|
507 |
581 |
EditConfigAttributes.CELL_EDITOR,
|
508 |
582 |
new QuantitativeDataCellEditor(feature.getRecommendedStatisticalMeasures(), this),
|
509 |
583 |
DisplayMode.EDIT,
|
510 |
|
getProperty(feature));
|
|
584 |
MatrixUtility.getProperty(feature));
|
511 |
585 |
}
|
512 |
586 |
else if(feature.isSupportsCategoricalData()){
|
513 |
587 |
//add display converter for string representation
|
... | ... | |
515 |
589 |
CellConfigAttributes.DISPLAY_CONVERTER,
|
516 |
590 |
new CategoricalDataDisplayConverter(),
|
517 |
591 |
DisplayMode.NORMAL,
|
518 |
|
getProperty(feature));
|
|
592 |
MatrixUtility.getProperty(feature));
|
519 |
593 |
|
520 |
594 |
//add combo box cell editor
|
521 |
595 |
CategoricalDataCellEditor comboBoxCellEditor = new CategoricalDataCellEditor(new IComboBoxDataProvider() {
|
... | ... | |
537 |
611 |
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR,
|
538 |
612 |
comboBoxCellEditor,
|
539 |
613 |
DisplayMode.EDIT,
|
540 |
|
getProperty(feature));
|
|
614 |
MatrixUtility.getProperty(feature));
|
541 |
615 |
|
542 |
616 |
}
|
543 |
617 |
|
... | ... | |
554 |
628 |
return rowWrappers;
|
555 |
629 |
}
|
556 |
630 |
|
557 |
|
private String getProperty(Feature feature){
|
558 |
|
return feature.getLabel();
|
559 |
|
}
|
560 |
|
|
561 |
631 |
public Map<Integer, Feature> getIndexToFeatureMap() {
|
562 |
632 |
return indexToFeatureMap;
|
563 |
633 |
}
|
ref #7095 Add summary row to top of grid