Adding a remove button to a column in a table
Asked Answered
C

4

8

Is it possible to add a Remove button to a cell in a table?

I have a table with 5 columns, I would like to add a 6th column. I want the 6th column to have a remove button in each row.

Example Row:

| 10002 | part | Metal | 001 | Yes | Remove |

That way the user can remove any unwanted rows by just clicking the button.

I have a markup column in the table and it is ComboBox. I created a class that extends EditingSupport.

Would I need to make a another class extending EditingSupport, but creating a button instead of ComboBox?

EDIT

public class AplotDataTableViewer extends TableViewer
{

    public AplotDataTableViewer(Composite parent, int style) 
    {
        super(parent, style);

        Table table = getTable();
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        table.setLayoutData(gridData);
        createColumns();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        setContentProvider(new ArrayContentProvider());
    }

    private void createColumns() {

      String[] titles = { "ItemId", "RevId", "PRL", "Dataset Name", "EC Markup" };
      int[] bounds = { 150, 150, 100, 150, 100 };

      TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
      col.setLabelProvider(new ColumnLabelProvider() {
         public String getText(Object element) {
            if(element instanceof AplotDataModel.AplotDatasetData)
               return ((AplotDataModel.AplotDatasetData)element).getDataset().toString();
            return super.getText(element); 
            }
         }); 

      col = createTableViewerColumn(titles[1], bounds[1], 1);
      col.setLabelProvider(new ColumnLabelProvider() {
         public String getText(Object element) {
            if(element instanceof AplotDataModel.AplotDatasetData)
               return ((AplotDataModel.AplotDatasetData)element).getRev().toString();
            return super.getText(element); 
            }
         });

      col = createTableViewerColumn(titles[2], bounds[2], 2);
      col.setLabelProvider(new ColumnLabelProvider() {
         public String getText(Object element) {
            if(element instanceof AplotDataModel.AplotDatasetData)
               return ((AplotDataModel.AplotDatasetData)element).getPRLValue().toString();
            return super.getText(element); 
            }
         });
      col = createTableViewerColumn(titles[3], bounds[3], 3);
      col.setLabelProvider(new ColumnLabelProvider() {
         public String getText(Object element) {
            if(element instanceof AplotDataModel.AplotDatasetData)
               return ((AplotDataModel.AplotDatasetData)element).getDatasetName().toString();
            return super.getText(element); 
            }
         });

       col = createTableViewerColumn(titles[4], bounds[4], 4);
       col.setLabelProvider(new ColumnLabelProvider() {
          public String getText(Object element) {
             if(element instanceof AplotDataModel.AplotDatasetData)
                return ((AplotDataModel.AplotDatasetData)element).getMarkupValue();
             return super.getText(element); 
             }
          });

       col.setEditingSupport(new OptionEditingSupport(this));

    }

    private TableViewerColumn createTableViewerColumn(String header, int width, int idx) 
    {
        TableViewerColumn column = new TableViewerColumn(this, SWT.LEFT, idx);
        column.getColumn().setText(header);
        column.getColumn().setWidth(width);
        column.getColumn().setResizable(true);
        column.getColumn().setMoveable(true);

        return column;
    }
}

EDIT

col = createTableViewerColumn(titles[5], bounds[5], 5);
   col.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public void update(ViewerCell cell) {
         TableItem item = new TableItem(getTable(),SWT.NONE);
         Button button = new Button(getTable(),SWT.NONE);
         button.setText("X");
         getControl().setBackground(item.getBackground());
         TableEditor editor = new TableEditor(getTable());
         editor.grabHorizontal  = true;
         editor.grabVertical = true;
         editor.setEditor(button , item, columnIndex);
         editor.layout();
         }
      });
Circumstantiality answered 18/9, 2012 at 15:41 Comment(0)
F
23

Here is sample working version.

public class TableEditorTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);

        shell.setLayout(new FillLayout());


        TableViewer viewer = new TableViewer(shell);
        viewer.getTable().setHeaderVisible(true);
        viewer.getTable().setLinesVisible(true);
        viewer.setContentProvider(new ArrayContentProvider());

        TableColumn column = new TableColumn(viewer.getTable(), SWT.NONE);
        column.setText("First Name");
        column.setWidth(100);
        TableViewerColumn firstNameCol = new TableViewerColumn(viewer, column);
        firstNameCol.setLabelProvider(new ColumnLabelProvider(){

            @Override
            public String getText(Object element) {
                Person p = (Person)element;

                return p.getFirstName();
            }

        });

        column = new TableColumn(viewer.getTable(), SWT.NONE);
        column.setText("Last Name");
        column.setWidth(100);
        TableViewerColumn lastNameCol = new TableViewerColumn(viewer, column);
        lastNameCol.setLabelProvider(new ColumnLabelProvider(){

            @Override
            public String getText(Object element) {
                Person p = (Person)element;

                return p.getLastName();
            }

        });




        column = new TableColumn(viewer.getTable(), SWT.NONE);
        column.setText("Actions");
        column.setWidth(100);
        TableViewerColumn actionsNameCol = new TableViewerColumn(viewer, column);
        actionsNameCol.setLabelProvider(new ColumnLabelProvider(){
            //make sure you dispose these buttons when viewer input changes
            Map<Object, Button> buttons = new HashMap<Object, Button>();


            @Override
            public void update(ViewerCell cell) {

                TableItem item = (TableItem) cell.getItem();
                Button button;
                if(buttons.containsKey(cell.getElement()))
                {
                    button = buttons.get(cell.getElement());
                }
                else
                {
                     button = new Button((Composite) cell.getViewerRow().getControl(),SWT.NONE);
                    button.setText("Remove");
                    buttons.put(cell.getElement(), button);
                }
                TableEditor editor = new TableEditor(item.getParent());
                editor.grabHorizontal  = true;
                editor.grabVertical = true;
                editor.setEditor(button , item, cell.getColumnIndex());
                editor.layout();
            }

        });



        Person p1 = new Person();
        p1.setFirstName("George");
        p1.setLastName("Burne");

        Person p2 = new Person();
        p2.setFirstName("Adam");
        p2.setLastName("Silva");

        Person p3 = new Person();
        p3.setFirstName("Nathan");
        p3.setLastName("Cowl");

        List<Person> persons = new ArrayList<Person>();
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);

        viewer.setInput(persons);

        shell.open();
        while(!shell.isDisposed())
        {

            if(!display.readAndDispatch())
            {
                display.sleep();
            }
        }

        display.dispose();

    }


    private static class Person
    {

        String firstName;
        String lastName;

        Person()
        {

        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

    }


}
Fylfot answered 19/9, 2012 at 0:23 Comment(1)
Please don't post multiple answers. You can edit you previous answer by using the "edit" link underneath it.Hollins
B
3

In addition to the answer from @sambi.reddy there is a comment that says - "make sure you dispose these buttons when viewer input changes". This is what I had to do to get that part working.

The framework I used had an implementation of IStructuredContentProvider, so in the overridden inputChanged(...), i had to put in the following code:-

@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

    // This will dispose of all the control button that were created previously
    if (((TableViewer)viewer).getTable() != null && ((TableViewer)viewer).getTable().getChildren() != null) {
        for (Control item : ((TableViewer)viewer).getTable().getChildren()) {
            // at this point there are no other controls embedded in the viewer, however different instances may require more checking of the controls here.
            if ((item != null) && (!item.isDisposed())) {  
                item.dispose();
            }
        }
    }
}

This works fine, except if you have a refresh table (ie. viewer.setInput(List)) call as the result of you button action. When I added this the following line sometimes returned buttons that still existed, but were being disposed:

if(buttons.containsKey(cell.getElement()))

So I needed to update this line to be:

if (buttons.containsKey(cell.getElement()) && !buttons.get(cell.getElement()).isDisposed())

Which resulted in any disposing buttons being recreated, if they were still required.

Birth answered 15/7, 2014 at 6:0 Comment(0)
E
1

One important thing to the chosen answer is that you should not create an instance of TableEditor on every update method call it will slow down the performance or even make the application unresposnive.

@Override
        public void update(ViewerCell cell) {

            TableItem item = (TableItem) cell.getItem();
            Button button;
            if(buttons.containsKey(cell.getElement()))
            {
                button = buttons.get(cell.getElement());
            }
            else
            {
                button = new Button((Composite) cell.getViewerRow().getControl(),SWT.NONE);
                button.setText("Remove");
                buttons.put(cell.getElement(), button);
                TableEditor editor = new TableEditor(item.getParent());
                editor.grabHorizontal  = true;
                editor.grabVertical = true;
                editor.setEditor(button , item, cell.getColumnIndex());
                editor.layout();
            }
        }
Enounce answered 23/4, 2014 at 10:26 Comment(0)
F
0

Below code should work for you

TableItem item = (TableItem) item;
Button button = new Button(table,swt.none);
button.setText("Remove");
control.setBackground(item.getBackground());
TableEditor editor = new TableEditor(table);
editor.grabHorizontal  = true;
editor.grabVertical = true;
editor.setEditor(button , item, columnIndex);
editor.layout();
Fylfot answered 18/9, 2012 at 16:10 Comment(5)
Where do you add that code? Does that go in the TableViewer class code? I will add my tableviewer class code above. Can you please show me how to add it.Circumstantiality
Please override ColumnLabelProvider.update(ViewerCell cell) for tableviewercolumn where you want to show this button. From ViewerCell you can get getItem, getColumnIndex. Make sure you keep track of the buttons that you are creating for each row object and dispose them when viewer input changes. Keep buttons in a map for each rowdata, before creating any button check it is already there in the map.Fylfot
I am sorry but I am having some problems trying incorporate your advice in my code. I need to read more about ViewerCellsCircumstantiality
Override update(ViewerCell cell) in ColumnLabelProvider instead getText() in your code and follow the code I provided above.Fylfot
I am going to paste the column code above. I get the column but there are no buttons visible. I am sure I have probably missed something elseCircumstantiality

© 2022 - 2024 — McMap. All rights reserved.