Remove button to remove itself

This article describes how to implement a table with SWT that holds several rows. Each row contains a button to remove this row.

This is tricky for two reasons:

  1. How to get a button into a table cell
  2. How let the button remove itself

The first part is described in this example. The trick is to use a TableEditor and put the button into it.
The problem with the second is that you want to execute a method on an object that removes itself. Therefor you have to delegate the removing.
All this together is shown in this piece of code:

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class TableTest {
  private Shell sShell = null;
  private Table table = null;
  private Button button = null;
  /** Main method */
  public static void main (String[] args){
    new TableTest().createSShell();
  }
  /**
   * This method initializes sShell
   */
  private void createSShell() {
    GridData gridData = new GridData();
    gridData.horizontalSpan = 2;
    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    sShell = new Shell();
    sShell.setText("Shell");
    sShell.setLayout(gridLayout);
    sShell.setSize(new Point(300, 200));
    table = new Table(sShell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
    table.setHeaderVisible(true);
    new Label(sShell, SWT.NONE);
    button = new Button(sShell, SWT.NONE);
    button.setText("Add");
    button.addSelectionListener(new SelectionAdapter(){
      public void widgetSelected(SelectionEvent e) {
        addRow();
      }
    });	
    String[] titles = { "Class Name", "Class package", "Generation Type" ,""}; //$NON-NLS-1$
    GridData gridData2 = new GridData(GridData.VERTICAL_ALIGN_END);
    gridData2.horizontalSpan = 2;
    gridData2.horizontalAlignment = GridData.FILL;
    gridData2.grabExcessHorizontalSpace=true;
    gridData2.grabExcessVerticalSpace=true;
    gridData2.heightHint=300;
    table.setLayoutData(gridData2);
    table.setLinesVisible(true);
    for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
      TableColumn column = new TableColumn(table, SWT.NULL);
      column.setText(titles[loopIndex]);
    }
    for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
      table.getColumn(loopIndex).pack();
    }
    // resize the row height using a MeasureItem listener
    table.addListener(SWT.MeasureItem, new Listener() {
      public void handleEvent(Event event) {
        // height cannot be per row so simply set
        event.height = 40;
      }
    });
  }
  /**
   * 
   */
  private void addRow() {
    TableItem item = new TableItem(table, SWT.NONE);
    item.setText(new String[] {"Class name","package.name","Type"});
    final TableEditor editor = new TableEditor(table);
    btnRemove = new Button(table,SWT.PUSH);
    btnRemove.setData(new Integer(table.getItemCount()-1));
    btnRemove.setText("remove");
    btnRemove.addSelectionListener(new SelectionAdapter(){
      @Override
      public void widgetSelected(SelectionEvent e) {
        final Display display = sShell.getDisplay();
        display.asyncExec(new Runnable(){
          public void run(){
            Button btn = (Button) editor.getEditor();
            btn.dispose();
            table.remove(0);
          }
        });
      }	
    });
    editor.grabHorizontal = true;
    editor.setEditor(btnRemove, item, 3);
  }
}

Known issue with the code above: If you have two rows and hit the remove button of the second, the second row and the remove button of the first is removed.

Ein Gedanke zu „Remove button to remove itself“

Schreibe einen Kommentar