protected void createTableViewer(Composite parent) { viewer = new FeatureTableViewer( parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); contentProvider = new LazyFeatureContentProvider(); contentProvider.filter(featureLayer.filter()); viewer.setContentProvider(contentProvider); // add columns DefaultFeatureTableColumn first = null; for (PropertyDescriptor prop : fs.getSchema().getDescriptors()) { if (Geometry.class.isAssignableFrom(prop.getType().getBinding())) { // skip Geometry } else { DefaultFeatureTableColumn column = new DefaultFeatureTableColumn(prop); // disable default sorting behaviour // column.setSortable( false ); viewer.addColumn(column); first = first != null ? first : column; // column.getViewerColumn().getColumn().addSelectionListener( new // SelectionAdapter() { // private SortOrder currentOrder = SortOrder.ASCENDING; // @Override // public void widgetSelected( SelectionEvent ev ) { // // with selection RAP produces huge JS which fails in browser // viewer.setSelection( StructuredSelection.EMPTY ); // currentOrder = currentOrder.equals( ASCENDING ) ? DESCENDING : // ASCENDING; // contentProvider.sort( column, currentOrder ); // } // }); } } // it is important to sort any column; otherwise preserving selection during refresh() // always selects a new element, which causes an event, which causes a refresh() ... first.sort(SWT.UP); // viewer.setInput(fs); // selection -> FeaturePanel viewer.addSelectionChangedListener( ev -> { on(ev.getSelection()) .first(IFeatureTableElement.class) .ifPresent( elm -> { log.info("selection: " + elm); featureLayer.setClicked(elm.unwrap(Feature.class).get()); BatikApplication.instance() .getContext() .openPanel(panel.site().path(), FeaturePanel.ID); }); }); }