在表格中的一列添加一个删除按钮

8

在表格的单元格中添加一个“移除”按钮是否可行?

我有一个有5列的表格,我想要添加第6列。我希望第6列每行都有一个删除按钮。

示例行:

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

这样用户就可以通过点击按钮来删除任何不需要的行。

在表格中我有一个标记列,它是一个ComboBox。我创建了一个扩展了EditingSupport的类。

我需要再创建一个扩展EditingSupport的类,但是这次创建一个按钮而不是ComboBox吗?

编辑

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;
    }
}

编辑

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();
         }
      });
4个回答

23

这是一个可工作的示例版本。

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;
        }

    }


}

4
请勿发布多个答案。您可以使用其下的“编辑”链接编辑您以前的答案。 - Baz

3
除了@sambi.reddy的回答之外,还有一个评论说:“确保在查看器输入更改时处理这些按钮”。这就是我需要做的才能使这部分工作正常。
我使用的框架有IStructuredContentProvider实现,因此在重写的inputChanged(...)中,我必须加入以下代码:
@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();
            }
        }
    }
}

这个方法很好用,但如果你在按钮操作后调用了刷新表格的方法(比如viewer.setInput(List)),就会出现问题。我发现有时候下面这行代码会返回一些已经被销毁的按钮:
if(buttons.containsKey(cell.getElement()))

所以我需要将这行更新为:

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

这导致任何需要重新创建的处理按钮,如果它们仍然需要的话。

1
重要提示:在更新方法调用时,不应创建TableEditor实例,否则会降低性能甚至使应用程序无响应。
@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();
            }
        }

0

以下代码应该适用于您

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();

你要把这段代码添加到哪里?是在TableViewer类中的代码吗?我会在我的TableViewer类代码上面添加。你能请演示一下如何添加吗? - jkteater
1
请在想要显示此按钮的tableviewercolumn中覆盖ColumnLabelProvider.update(ViewerCell cell)方法。从ViewerCell中,您可以获取getItem和getColumnIndex。确保跟踪您为每个行对象创建的按钮,并在查看器输入更改时将其处理。将按钮保存在每个rowData的映射中,在创建任何按钮之前,请检查它是否已经存在于映射中。 - sambi reddy
很抱歉,我在将您的建议融入我的代码时遇到了一些问题。我需要多读一些有关ViewerCells的内容。 - jkteater
在你的代码中,覆盖ColumnLabelProvider中的update(ViewerCell cell)方法而不是getText()方法,并按照我提供的代码进行操作。 - sambi reddy
我将把列代码粘贴在上面。我得到了这一列,但没有任何按钮可见。我相信我可能还错过了其他的东西。 - jkteater

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接