NatTable filtering row header layer for dynamic list - nattable

When I use dynamic list for Nattable the filtering via filter header layer it does not work for me.
I want to be able to filter all columns. I have respective code for each column in the filter row configuration class and it works if the input is a static list.
Attached my code snippet:
public Control createPeopleTable(Composite parent) {
// create a new ConfigRegistry which will be needed for GlazedLists
configRegistry = new ConfigRegistry();
peopleTableColumns = PeopleTableColumnDefinition.getPeopleTableColumns();
final Map<String, String> propertyToLabelMap = new HashMap<>();
final String[] propertyNames = new String[peopleTableColumns.size()];
for (int i = 0; i < peopleTableColumns.size(); ++i) {
final PeopleTableColumnDefinition col = peopleTableColumns.get(i);
propertyNames[i] = col.getProperty();
propertyToLabelMap.put(propertyNames[i], col.getDisplayName());
}
columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<>(propertyNames);columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<>(propertyNames);
peopleList = new ArrayList<>();
eventList = GlazedLists.eventList(peopleList);
dynamicValues = GlazedLists.threadSafeList(eventList);
bodyLayerStack = new BodyLayerStack(dynamicValues, columnPropertyAccessor);
.....
IFilterStrategy<People> filterStrategy = new DefaultGlazedListsFilterStrategy<>(
bodyLayerStack.getFilterList(), columnPropertyAccessor, configRegistry);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<People> filterRowHeaderLayer = new FilterRowHeaderComposite<>(filterStrategy,
sortHeaderLayer, bodyLayerStack.getBodyDataProvider(), configRegistry);
// build the row header layer
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyLayerStack.getBodyDataProvider());
DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, bodyLayerStack,
bodyLayerStack.getSelectionLayer());
// build the corner layer
IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider,
rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, filterRowHeaderLayer);
// build the grid layer
GridLayer gridLayer = new GridLayer(bodyLayerStack, filterRowHeaderLayer, rowHeaderLayer, cornerLayer);
// turn the auto configuration off as we want to add our header menu
// configuration
natTable = new NatTable(parent, gridLayer, false);
.....
natTable.addConfiguration(new FilterRowConfiguration());
natTable.configure();
...
return natTable;
}
class FilterRowConfiguration extends AbstractRegistryConfiguration {
#Override
public void configureRegistry(IConfigRegistry configRegistry) {
// register the FilterRowTextCellEditor in the first column which
// immediately commits on key press
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new FilterRowTextCellEditor(),
DisplayMode.NORMAL, FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
+ PeopleTableColumnDefinition.Name.columnIndex());
.....
}
class BodyLayerStack extends AbstractLayerTransform {
private FilterList<People> filterList;
private final SelectionLayer selectionLayer;
private SortedList<People> sortedList;
private ViewportLayer viewportLayer;
public BodyLayerStack(EventList<People> values,
IColumnPropertyAccessor<People> columnPropertyAccessor) {
// use the SortedList constructor with 'null' for the Comparator
// because the Comparator
// will be set by configuration
sortedList = new SortedList<>(values, null);
// wrap the SortedList with the FilterList
filterList = new FilterList<>(sortedList);
peopleListDataProvider = new PeopleListDataProvider<>(filterList, columnPropertyAccessor);
bodyDataLayer = new DataLayer(peopleListDataProvider);
final ColumnOverrideLabelAccumulator columnLabelAccumulator = new ColumnOverrideLabelAccumulator(
bodyDataLayer);
for (int i = 0; i < peopleTableColumns.size(); i++) {
PeopleTableColumnDefinition peopleTableColumnDefinition = peopleTableColumns.get(i);
columnLabelAccumulator.registerColumnOverrides(i, peopleTableColumnDefinition.getTableLabel());
}
bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<People> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer,
filterList);
selectionLayer = new SelectionLayer(glazedListsEventLayer);
viewportLayer = new ViewportLayer(selectionLayer);
FreezeLayer freezeLayer = new FreezeLayer(selectionLayer);
compositeFreezeLayer = new CompositeFreezeLayer(freezeLayer, viewportLayer, selectionLayer);
setUnderlyingLayer(compositeFreezeLayer);
}
public SortedList<People> getSortedList() {
return sortedList;
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
public FilterList<People> getFilterList() {
return this.filterList;
}
public PeopleListDataProvider<People> getBodyDataProvider() {
return peopleListDataProvider;
}
}
public void setListOfPeople(List<People> listOfPeople) {
this.eventList.getReadWriteLock().writeLock().lock();
this.dynamicValues.getReadWriteLock().writeLock().lock();
try {
peopleList.clear();
eventList.clear();
dynamicValues.clear();
peopleList.addAll(listOfPeople);
eventList.addAll(listOfPeople);
dynamicValues.addAll(listOfPeople);
peopleListDataProvider.setPeopleList(peopleList);
} finally {
eventList.getReadWriteLock().writeLock().unlock();
dynamicValues.getReadWriteLock().writeLock().unlock();
}
}

It seems you haven't understood the principles of GlazedLists and Java object references.
First you don't have to call clear() and addAll() on all lists. The GlazedLists are views on the base list, so it should be enough to call on the EventList or a higher list like the FilterList.
Second mistake is that you set another list on the IDataProvider. And that list is not the FilterList. So actually you disable the filter as the FilterList is doing the filter magic. And setting the list is not necessary as you performed a list modification. So why changing it then?

Related

Auto resize row heights while sorting or filtering

I can not handle auto row heights resizing.
I tried to use AutomaticRowHeightExample, but without success.
Another inspiration was this question, but also did not worked (see my code example). If I sort/filter, in console output I can see numbers of painted rows i while creating PaintListener, but row heights are not updated.
Creating table:
public class NatTableFactory {
// another code
private NatTable createTable(Composite parent, List<TableLine> tLines, String[][] propertyNames,
PropertyToLabels[] propToLabels, TableParams params, TextMatcherEditor<TableLine>editor, boolean openableParts) {
BodyLayerStack bodyLayerStack =
new BodyLayerStack(
tLines,
tLines.get(0).getLength(),
params.getColumnIndicesForRowHeaders());
DataLayer bodyDataLayer = bodyLayerStack.getBodyDataLayer();
Integer[] rowHeights = getRowHeights(params);
if( rowHeights != null && rowHeights.length > 0 ) {
for( int i = 0; i < rowHeights.length; i++ ) {
if( rowHeights[i] != null )
bodyDataLayer.setRowHeightByPosition(i, (int) (rowHeights[i] * ApplicationSizeManager.getRowSizeCoefficient()));
}
}
Integer[] colWidths = getColumnWidths(params);
if( colWidths != null && colWidths.length > 0 ) {
for( int i = 0; i < colWidths.length; i++ )
if( colWidths[i] != null )
bodyDataLayer.setColumnWidthByPosition(i, colWidths[i]);
}
DataLayer columnHeaderDataLayer = null;
if( propertyNames != null ) {
IDataProvider columnHeaderDataProvider =
new DefaultColumnHeaderDataProvider(propertyNames[0], propToLabels[0].getPropertyToLabels());
columnHeaderDataLayer =
new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
}
//copy command: include table headers
bodyLayerStack.registerCommandHandler(new CustomCopyDataCommandHandler(bodyLayerStack.getSelectionLayer(), columnHeaderDataLayer, null, params.getColumnHeaderGroups()));
CompositeLayer composite = null;
if( propertyNames != null ) {
ColumnHeaderLayer columnHeaderLayer =
new ColumnHeaderLayer(
columnHeaderDataLayer,
bodyLayerStack,
(SelectionLayer)null);
columnHeaderLayer.addConfiguration(NatTableLayerConfigurations.getColumnHeaderLayerConfiguration(false));
SortHeaderLayer<TableLine> sortHeaderLayer =
new SortHeaderLayer<TableLine>(
columnHeaderLayer,
new GlazedListsSortModel<TableLine>(
bodyLayerStack.getSortedList(),
getSortingColumnPropAccessor(propertyNames[0]),
configRegistry,
columnHeaderDataLayer));
Integer[] hrHeights = params.getHeaderRowHeights();
if( hrHeights != null && hrHeights.length > 0 )
columnHeaderDataLayer.setRowHeightByPosition(0, (int) (hrHeights[0] * ApplicationSizeManager.getRowSizeCoefficient()));
composite = new CompositeLayer(1, 2);
composite.setChildLayer(GridRegion.COLUMN_HEADER, sortHeaderLayer, 0, 0);
composite.setChildLayer(GridRegion.BODY, bodyLayerStack, 0, 1);
} else {
composite = new CompositeLayer(1, 1);
composite.setChildLayer(GridRegion.BODY, bodyLayerStack, 0, 0);
}
composite.addConfiguration(NatTableLayerConfigurations.getCompoositeLayerConfiguration());
NatTable natTable = new NatTable(parent, composite, false);
if( params.getAutoFitColWidthIndices().size() > 0 )
registerAutoResizeColCmdHandler(natTable, composite, bodyLayerStack, params.getAutoFitColWidthIndices());
// register AutoResizeRowCommandHandler
// something wrong here?
registerAutoResizeRowCommandHandler(natTable, composite, bodyLayerStack, params.getAutoFitColWidthIndices());
setNatTableContentTooltip(natTable);
natTable.setConfigRegistry(configRegistry);
natTable.addConfiguration(new SingleClickSortConfiguration());
if(columnHeaderDataLayer!=null)
natTable.addConfiguration(NatTableLayerConfigurations.getCustomComparatorConfiguration(columnHeaderDataLayer));
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
setNatTableContextMenu(natTable, openableParts);
natTable.addConfiguration(NatTableLayerConfigurations.getNatTableConfiguration());
//
/*
natTable.addConfiguration(new DefaultNatTableStyleConfiguration()
{
{
cellPainter = new LineBorderDecorator(new AutomaticRowHeightTextPainter(5));
}
});*/
natTable.configure();
editor.setFilterator(new TextFilterator<TableLine>() {
#Override
public void getFilterStrings(List<String> baseList, TableLine element) {
for( int i = 0; i < element.getLength(); i++ )
baseList.add("" + element.getObjectByColumnForFilter(i));
}
});
editor.setMode(TextMatcherEditor.REGULAR_EXPRESSION);
bodyLayerStack.getFilterList().setMatcherEditor(editor);
NatTableContentProvider.addNatTableData(natTable, bodyLayerStack.getSelectionLayer(), bodyLayerStack.getBodyDataProvider());
return natTable;
}
// another code
}
register AutoResizeRowCommandHandler:
// in class NatTableFactory
private void registerAutoResizeRowCommandHandler(NatTable natTable, ILayer commandLayer, ILayer positionLayer, List<Integer> colPositions)
{
natTable.registerCommandHandler(new AutoResizeRowCommandHandler(commandLayer, positionLayer));
PaintListener listener = new PaintListener()
{
#Override
public void paintControl(PaintEvent e)
{
System.out.println("paintControl");
for (int i = 0; i < natTable.getRowCount(); i++)
{
System.out.println(i);
InitializeAutoResizeRowsCommand rowCommand = new InitializeAutoResizeRowsCommand(natTable, i, natTable.getConfigRegistry(), new GCFactory(
natTable));
AutoResizeRowsCommand command = new AutoResizeRowsCommand(rowCommand);
natTable.doCommand(command);
}
}
};
natTable.addPaintListener(listener);
}
BodyLayerStack:
public BodyLayerStack(List<TableLine> values, int columnCount, Integer[] columnIndicesForRowHeaders)
{
EventList<TableLine> eventList = GlazedLists.eventList(values);
TransformedList<TableLine, TableLine> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
// this.filterList = new FilterList<>(rowObjectsGlazedList); //changed to:
// use the SortedList constructor with 'null' for the Comparator
// because the Comparator will be set by configuration
sortedList = new SortedList<>(rowObjectsGlazedList, null);
// wrap the SortedList with the FilterList
filterList = new FilterList<>(sortedList);
bodyDataProvider = new ListDataProvider<TableLine>(filterList, getColumnAccessor(columnCount));
bodyDataLayer = new DataLayer(bodyDataProvider);
IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
#Override
public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
int columnIndex = bodyDataLayer.getColumnIndexByPosition(columnPosition);
int rowIndex = bodyDataLayer.getRowIndexByPosition(rowPosition);
if(isRowHeader(columnIndicesForRowHeaders, columnIndex))
configLabels.addLabel(NatTableFactory.RowHeaderLabel);
else
{
// get dataTypes at actual positions and add/refresh labels
String label = filterList.get(rowIndex).getObjectTypeByColumn(columnIndex);
// adjust label according to autoFitWitdh option
if(filterList.get(rowIndex).isAutoFitColWidth(columnIndex))
label += "_" + NatTableFactory.AutoFitWidthLabel;
else
label += "_" + NatTableFactory.NoAutoFitWidthLabel;
configLabels.addLabel(label);
}
}
};
bodyDataLayer.setConfigLabelAccumulator(cellLabelAccumulator);
GlazedListsEventLayer<TableLine> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer, filterList);
selectionLayer = new SelectionLayer(glazedListsEventLayer, false);
selectionLayer.setSelectionModel(getSelectionModel());
selectionLayer.addConfiguration(getSelectionConfiguration());
//
viewportLayer = new ViewportLayer(selectionLayer);
setUnderlyingLayer(new ViewportLayer(selectionLayer));
}
If I call natTable.doCommand(rowCommand) instead of natTable.doCommand(command) while registering handler, row heights are updated correctly, but table is painted repetitively, scroll bar blinks all the time.
I tried also:
private void registerAutoResizeRowCommandHandler(NatTable natTable, ILayer commandLayer, ILayer positionLayer, List<Integer> colPositions)
{
natTable.registerCommandHandler(new AutoResizeRowCommandHandler(commandLayer, positionLayer));
BodyLayerStack bodyLayerStack = (BodyLayerStack) positionLayer;
natTable.addPaintListener(
new AutoResizeRowPaintListener(
natTable,
bodyLayerStack.getViewportLayer(),
bodyLayerStack.getBodyDataLayer()));
}
Any idea what did I miss?
Well for a complete answer I would need quite some time to explain the internals of NatTable. Not sure if you are really interested in this. So I simply answer how to do it right.
With NatTable 1.6 the AutoResizeRowPaintListener was added to simplify the auto row resize task. Information about this can be found here: https://www.eclipse.org/nattable/nandn/nandn_160.php
I have got it:
in NatTableFactory:
private NatTable createTable(Composite parent, List<TableLine> tLines, String[][] propertyNames,
PropertyToLabels[] propToLabels, TableParams params, TextMatcherEditor<TableLine>editor,
boolean openableParts)
{
// another code
registerAutoResizeRowCommandHandler(natTable, composite, bodyLayerStack);
//another code
return natTable;
}
and:
private void registerAutoResizeRowCommandHandler(NatTable natTable,
CompositeLayer commandLayer, BodyLayerStack bodyLayerStack)
{
natTable.registerCommandHandler(new AutoResizeRowCommandHandler(commandLayer, bodyLayerStack));
natTable.addPaintListener(
new AutoResizeRowPaintListener(
natTable,
bodyLayerStack.getViewportLayer(),
bodyLayerStack.getBodyDataLayer()));
}
My mistake was in BodyLayerStack:
viewportLayer = new ViewportLayer(selectionLayer);
setUnderlyingLayer(new ViewportLayer(selectionLayer));
correct is:
viewportLayer = new ViewportLayer(selectionLayer);
setUnderlyingLayer(viewportLayer);
Thanks Dirk Fauth!

Sorting in NatTables

I have got implemented filtering in nattables. How to add sorting? do I have to create new columnHeaderLayer? Here is my code:
1 class BodyLayerStack
class BodyLayerStack extends AbstractLayerTransform {
private final FilterList<TableLine> filterList;
private final SelectionLayer selectionLayer;
private final DataLayer bodyDataLayer;
private final IRowDataProvider<TableLine> bodyDataProvider;
private final SortedList<TableLine> sortedList;
public DataLayer getBodyDataLayer() {
return bodyDataLayer;
}
public SelectionLayer getSelectionLayer() {
return selectionLayer;
}
public IRowDataProvider<TableLine> getBodyDataProvider() {
return bodyDataProvider;
}
getting values from tables:
public BodyLayerStack(List<TableLine> values, IColumnAccessor<TableLine> columnAccessor, Integer[] columnIndicesForRowHeaders) {
EventList<TableLine> eventList = GlazedLists.eventList(values);
TransformedList<TableLine, TableLine> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
creating filter and sorted list:
this.filterList = new FilterList<>(rowObjectsGlazedList);
this.sortedList = new SortedList<>(filterList, null);
this.bodyDataProvider = new ListDataProvider<TableLine>(this.sortedList, columnAccessor);
bodyDataLayer = new DataLayer(this.bodyDataProvider);
ColumnOverrideLabelAccumulator bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
if( columnIndicesForRowHeaders != null ) {
for ( int i = 0; i < columnIndicesForRowHeaders.length; i++ ) {
bodyLabelAccumulator.registerColumnOverrides(
columnIndicesForRowHeaders[i],
RowHeaderLabel);
}
}
event layer:
GlazedListsEventLayer<TableLine> glazedListsEventLayer =
new GlazedListsEventLayer<>(bodyDataLayer, this.filterList);
this.selectionLayer = new SelectionLayer(glazedListsEventLayer, false);
selectionLayer.setSelectionModel(new RowSelectionModel<TableLine>(selectionLayer, this.bodyDataProvider, new IRowIdAccessor<TableLine>()
{
#Override
public Serializable getRowId(TableLine line)
{
return line.getId();
}
}));
adding configuration to selection layer
selectionLayer.addConfiguration(new DefaultSelectionLayerConfiguration()
{
#Override
protected void addSelectionUIBindings()
{
addConfiguration(new SelectionBindings());
}
#SuppressWarnings("rawtypes")
#Override
protected void addMoveSelectionConfig()
{
addConfiguration(new RowOnlySelectionConfiguration());
}
});
viewport layer + return
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
setUnderlyingLayer(viewportLayer);
}
public FilterList<TableLine> getFilterList() {
return this.filterList;
}
}
If you want to add sorting by click on column header cells, you have to add the SortHeaderLayer to your column header layer stack.
Please check the NatTable examples, like for example the SortableFilterableColumnGroupExample

want to create drop down list (Combo box viewer) in TreeColumn in SWT

I am using Tree and in this tree I have a five treecolumn. Also create two treeItem one is parent and other child, put their values in treecolumn by programatically. Now I need a dropdown List(Combobox) in each tree column(except first one) to view the list data. Currently getting only single value. Please see the below code to get tree item values editable in treecolumn.
private void editTreeTable(final Tree table){
final TreeEditor editor = new TreeEditor(table);
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseUp(final MouseEvent e) {
final Control oldEditor = editor.getEditor();
if (oldEditor != null) {
oldEditor.dispose();
}
final Point p = new Point(e.x, e.y);
final TreeItem item = table.getItem(p);
if (item == null) {
return;
}
for (int i = 1; i < table.getColumnCount(); ++i) {
if (item.getBounds(i).contains(p)) {
final int columnIndex = i;
// The control that will be the editor must be a
final Text newEditor = new Text(table, SWT.NONE);
newEditor.setText(item.getText(columnIndex ));
newEditor.addModifyListener(new ModifyListener() {
public void modifyText(final ModifyEvent e) {
final Text text = (Text) editor.getEditor();
editor.getItem().setText(columnIndex , text.getText());
}
});
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item, columnIndex );
}
}
}
});
}
Now find the below code to get the tree item value from API
private void createTestSuiteTable( final Tree table)
{
//Dispose all elements
TreeItem items[] = table.getItems();
for(int i=0;i<items.length;i++)
{
items[i].dispose();
}
TSGson tsGsons[] = TestSuiteAPIHandler.getInstance().getAllTestSuites();
boolean checked=false;
for (TSGson tsGson : tsGsons)
{
parentTestSuite = new TreeItem(table, SWT.NONE|SWT.MULTI);
parentTestSuite.setText(new String[] { "" +tsGson.tsName, "", "","","","" });
parentTestSuite.setData("EltType","TESTSUITE");
if(tsGson.tsTCLink==null)
continue;
for(TSTCGson tsTCGson : tsGson.tsTCLink)
{
TreeItem trtmTestcases = new TreeItem(parentTestSuite, SWT.NONE|SWT.MULTI);
trtmTestcases.setText(new String[] {tsTCGson.tcName,
tsTCGson.tcParams.get(0)!=null ?tsTCGson.tcParams.get(0).tcparamValue:"",
tsTCGson.tcParams.get(1)!=null ?tsTCGson.tcParams.get(1).tcparamValue:"",
tsTCGson.tcParams.get(2)!=null ?tsTCGson.tcParams.get(2).tcparamValue:"",
"local",
tsTCGson.tcParams.get(4)!=null ?tsTCGson.tcParams.get(4).tcparamValue:"" });
trtmTestcases.setData("EltType","TESTCASE");
table.setSelection(parentTestSuite);
if(checked)
{
trtmTestcases.setChecked(checked);
}
}
}
}
Find the below code for tree column creation in SWT
localHostTable = new Tree(composite_2,SWT.BORDER | SWT.CHECK | SWT.FULL_SELECTION | SWT.VIRTUAL);
localHostTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
localHostTable.setLinesVisible(true);
localHostTable.setHeaderVisible(true);
TreeColumn trclmnNewColumn_1 = new TreeColumn(localHostTable, SWT.NONE);
trclmnNewColumn_1.setWidth(113);
trclmnNewColumn_1.setText("TestSuite/TestCase");
TreeColumn trclmnColumn_5 = new TreeColumn(localHostTable, SWT.NONE);
trclmnColumn_5.setWidth(73);
trclmnColumn_5.setText("Exe_Platform");
TreeColumn trclmnColumn_6 = new TreeColumn(localHostTable, SWT.NONE);
trclmnColumn_6.setWidth(77);
trclmnColumn_6.setText("Exe_Type");
TreeColumn trclmnColumn_7 = new TreeColumn(localHostTable, SWT.NONE);
trclmnColumn_7.setWidth(85);
trclmnColumn_7.setText("Run_On");
TreeColumn trclmnColumn_8 = new TreeColumn(localHostTable, SWT.NONE);
trclmnColumn_8.setWidth(81);
trclmnColumn_8.setText("Thread-Count");
final TreeColumn trclmnColumn_9 = new TreeColumn(localHostTable, SWT.NONE);
trclmnColumn_9.setWidth(97);
trclmnColumn_9.setText("Column5");
please suggest
Since there's nothing in your question about Combo or CCombo controls, I can't help you troubleshoot an issue. I also am not going to write your code for you, but I can try to point you in the right direction with a short example.
Yes, i want the combo to always be visible.
You can still use a TreeEditor to accomplish this, and it will actually be simpler than the code snippet you posted with the MouseListener.
Create the CCombo (or Combo) as you would in any other situation, and use TreeEditor.setEditor(...) methods to specify that the CCombo control should be displayed in that cell:
// ...
final CCombo combo = new CCombo(tree, SWT.NONE);
final TreeEditor editor = new TreeEditor(tree);
editor.setEditor(combo, item, 1);
// ...
Full MCVE:
public class TreeComboBoxTest {
private final Display display;
private final Shell shell;
public TreeComboBoxTest() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new FillLayout());
final Tree tree = new Tree(shell, SWT.BORDER | SWT.VIRTUAL | SWT.FULL_SELECTION);
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
tree.setLinesVisible(true);
tree.setHeaderVisible(true);
final TreeColumn column1 = new TreeColumn(tree, SWT.NONE);
column1.setWidth(75);
column1.setText("Column 1");
final TreeColumn column2 = new TreeColumn(tree, SWT.NONE);
column2.setWidth(75);
column2.setText("Column 2");
final TreeItem item = new TreeItem(tree, SWT.NONE);
item.setText(0, "Hello");
final CCombo combo = new CCombo(tree, SWT.NONE);
combo.setItems(new String[] { "Item 1", "Item 2", "Item 3" });
final TreeEditor editor = new TreeEditor(tree);
editor.setEditor(combo, item, 1);
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
// Optional, but allows you to get the current value by calling
// item.getText() instead of going through the TreeEditor and
// calling ((CCombo) editor.getEditor()).getText()
combo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
item.setText(1, combo.getText());
}
});
}
public void run() {
shell.setSize(200, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void main(final String... args) {
new TreeComboBoxTest().run();
}
}
Note the SelectionListener added to the CCombo. Even though you've used the TreeEditor, if you call item.getText(index), it will return an empty String because setText(...) has not been called. By calling setText(...) in the listener, you won't have to go through the TreeEditor to get the value.
So you can call item.getText(index) instead of ((CCombo) editor.getEditor()).getText().

Eclipse Plugin display data as table

I'm writing an Eclipse plugin that calls a program and will display the resulting data an a table in a view.
I have successfully gotten data from the call, but have not been able to display it.
here is my code (edited for brevity)
static Vector results ;
/**
* the command has been executed, so extract extract the needed information
* from the application context.
*/
public Object execute(ExecutionEvent event) throws ExecutionException {
try{
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
IWorkbenchPage pg = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage();
ObjectWhereUsedInputDialog gtid = new ObjectWhereUsedInputDialog(window.getShell());
ArrayList<Object> input = gtid.openDialog();
CallProgram callPrg = new CallProgram();
String callPCML = "callPcml";
int idx = (input.size()-1);
AS400 as400 = (AS400) input.get(idx);
input.remove(idx);
results = callPrg.callProgram(as400, input);
ObjectWhereUsedResultTableView dlg = new ObjectWhereUsedResultTableView(results);
public void createPartControl(Composite parent) {
Table myTable = new Table (parent, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL );
myTable.setHeaderVisible (true);
myTable.setLinesVisible (true);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.heightHint = 200;
myTable.setLayoutData(data);
String[] titles = getColumns(myTable);
for (int i=0; i<titles.length; i++) {
TableColumn column = new TableColumn (myTable, SWT.NONE);
column.setText (titles [i]);
}
if(data!=null){System.out.println("datag "+data.size());};
createTable(myTable, data);
for (int i=0; i<titles.length; i++) {
myTable.getColumn (i).pack ();
}
parent.layout(true);
parent.pack();
}
TableRow[] createTable(Table myTable, Vector<String> dataLines){
String[] columns = this.getColumns(myTable);
for (int i=0; i<columns.length; i++) {
TableColumn column = new TableColumn (myTable, SWT.NONE);
column.setText (columns[i]);
}
int dSize = dataLines==null||dataLines.isEmpty()?0:dataLines.size();
for(int i = 0;i<dSize;i++){
String[] elements = dataLines.get(i).split(",");
TableItem item = new TableItem (myTable, SWT.NONE);
for(int j = 0;j<elements.length;j++){
String itemStr = elements[j].isEmpty()?" ":elements[j];
item.setText(j,itemStr);
}
}
To show a view you must use IWorkbenchPage.showView:
ObjectWhereUsedResultTableView view = (ObjectWhereUsedResultTableView)pg.showView("the view id");
This will construct the view part using a no-argument public constructor:
public ObjectWhereUsedResultTableView()
{
...
}
You cannot pass arguments to the constructor.
To set data in the view you must add an extra method which you call after showing the view:
view.setData(data);
where setData is a method you write that updates the table with the data.
Note: You might find TableViewer easier to use than Table.

Drag and drop for tableviewer in SWT

I need to Drag tableViewer cell value to another tableViewer cell in swt.
I need to remove that value where i dragged and add those value where i dropped in tableViewer i'm able to drag and drop but not able to drop where i want too and not able to remove and add value when i drag and drop in tableviewer. Here is the i have:Thank in advance for help.
public void DragandDrop(){
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
DragSource source = new DragSource(table_2, DND.DROP_MOVE | DND.DROP_COPY);
source.setTransfer(types);
source.addDragListener(new DragSourceAdapter() {
public void dragSetData(DragSourceEvent event) {
DragSource ds = (DragSource) event.widget;
Table table = (Table) ds.getControl();
TableItem[] selection = table.getSelection();
StringBuffer buff = new StringBuffer();
for (int i = 0, n = selection.length; i < n; i++) {
buff.append(selection[i].getText());
}
event.data = buff.toString();
}
});
DropTarget target = new DropTarget(table_3, DND.DROP_MOVE | DND.DROP_COPY );
target.setTransfer(types);
target.addDropListener(new DropTargetAdapter() {
public void dragEnter(DropTargetEvent event) {
if (event.detail != DND.DROP_DEFAULT) {
event.detail = (event.operations & DND.DROP_COPY) != 0 ? DND.DROP_COPY : DND.DROP_NONE;
}
for (int i = 0, n = event.dataTypes.length; i < n; i++) {
if (TextTransfer.getInstance().isSupportedType(event.dataTypes[i])) {
event.currentDataType = event.dataTypes[i];
}
}
}
public void dragOver(DropTargetEvent event) {
event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
}
public void drop(DropTargetEvent event) {
if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
DropTarget target = (DropTarget) event.widget;
Table table = (Table) target.getControl();
String data = (String) event.data;
TableItem item = new TableItem(table, SWT.NONE);
item.setText(new String[] { data });
// table.redraw();
}
}
});
}
to remove the selected value you can use follows
public void drop(DropTargetEvent event) {
if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
DropTarget target = (DropTarget) event.widget;
Table table = (Table) target.getControl();
String data = (String) event.data;
TableItem item = new TableItem(table, SWT.NONE);
item.setText(new String[] { data });
//remove the tableitem you drag
table.remove(table.getSelectionIndex());
}
I was looking for Drag and Drop on TableViewer and found the solutions. Hope everyone understand easily. My case, I created two new Listener class inheritance from DragSourceListener & DropTargetListener. Because I want to use TableViewer functions. You need three things to do.
First save index of source item from void dragStart(DragSourceEvent event),
Seconds set data into event.data and
Then Last found target index from void drop(DropTargetEvent event).
public class TestClass extends TableViewer {
private int sourceIndex;
priavte class DragListener implements DragSourceListener {
private TableViewer viewer;
public ItemDragListener(TableViewer viewer) {
this.viewer = viewer;
}
public void dragStart(DragSourceEvent event) {
sourceIndex = viewer.getTable().getSelectionIndex();
}
public void dragSetData(DragSourceEvent event) {
// save data
ISelection select = viewer.getSelection();
if (select instanceof IStructuredSelection) {
Object item = (Object) ((IStructuredSelection)select).getFirstElement();
// save item to event.data
event.data = .........
}
:
}
private class ItemDropListener implements DropTargetListener {
TableViewer viewer;
public ItemDropListener(TableViewer viewer) {
this.viewer = viewer;
}
public void drop(DropTargetEvent event) {
if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
TableItem item = (TableItem)event.item;
int targetIndex= -1;
if (item != null) {
Table table = item.getParent();
targetIndex= table.indexOf(item);
}
String data = (String) event.data;
// add an item
if (targetIndex >= 0)
viewer.insert((Object)data, targetIndex);
else
viewer.add((Object)data);
// remove an item
viewer.getTable().remove(sourceIndex); // Careful, it can be changed after add an item
}
}
public void init() {
Transfer[] transfers = new Transfer[] { TextTransfer.getInstance() };
this.addDragSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new ItemDragListener(this));
this.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new ItemDropListener(this));
}
}