开始编辑在 tableviewer 中添加的最新行

Start to edit the newest row added in a tableviewer

我有一个树查看器,其中一列包含字符串。 我做了一个 "add button".

我想要的是当用户添加一行时,我想将 "edit cursor" 移动到新行。

我有两个问题:

  1. 当我使用

    添加新数据时

    tableViewer.add()

tableViewer.getTable().getItemCount() 没有更新!所以我不能 select 最后一行...

另外,当我设置 ColumnViewerEditorActivationStrategy 时。我不能再 select tableViewer.setSelection()

  1. 不知道怎么触发编辑模式

这里是详细的源代码

public class CompositeTableViewer extends Composite {
private TableViewer tableViewer;

private List<String> columnNames;

int correctionSelection = 0;

public CompositeTableViewer(Composite parent, int style, List<String> columnNames, boolean rowAddable)
{
    this(parent, style, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, columnNames, rowAddable);
}

public CompositeTableViewer(Composite parent, int style, int tableViewerStyle, List<String> columnNames, boolean rowAddable)
{
    super(parent, style);

    GridLayout layout = new GridLayout(3, false);
    layout.marginWidth = 4;
    this.setLayout(layout);

    this.setBackground(SWTResourceManager.getColor(SWT.COLOR_DARK_RED));
    setTableViewer(new TableViewer(this, tableViewerStyle));

    TextCellEditor columnEditor = new TextCellEditor(tableViewer.getTable());
    CellEditor[] editors = { columnEditor };
    this.columnNames = columnNames;
    tableViewer.setColumnProperties(this.columnNames.toArray(new String[this.columnNames.size()]));
    tableViewer.setContentProvider(new ArrayContentProvider());
    tableViewer.setLabelProvider(new LabelProvider());
    tableViewer.setCellEditors(editors);
    tableViewer.setCellModifier(new StringListCellModifier(this));

    //here I restricted the edit activation to double-click 
    changeColumnViewerEditorActivationStrategy();

    final Table table = tableViewer.getTable();
    table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
    table.setLinesVisible(true);

    createButtons(this, rowAddable);

}

    public void setInput(List<Object> dataList)
    {
        this.tableViewer.setInput(dataList);
    }
    /**
     * change the edition activation to double click
     * otherwise that's block multi selection :/
     * 
     */
    public TableViewerFocusCellManager changeColumnViewerEditorActivationStrategy()
    {
        TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer, new FocusCellOwnerDrawHighlighter(tableViewer));

        ColumnViewerEditorActivationStrategy activationSupport = new ColumnViewerEditorActivationStrategy(tableViewer)
        {
            protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event)
            {
                // Enable editor only with mouse double click
                if (event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION)
                {
                    EventObject source = event.sourceEvent;
                    if (source instanceof MouseEvent && ((MouseEvent) source).button == 3)
                        return false;

                    return true;
                }

                return false;
            }
        };

        TableViewerEditor.create(tableViewer, focusCellManager, activationSupport, ColumnViewerEditor.TABBING_HORIZONTAL
                | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);

        return focusCellManager;
    }


    /**
     * Add the "Add" and "Delete" buttons
     * 
     * @param parent
     *            the parent composite
     */
    private void createButtons(Composite parent, boolean rowAddable)
    {

        // Create and configure the "Add" button
        Button add = new Button(parent, SWT.PUSH | SWT.CENTER);
        add.setText("Add");

        GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        gridData.widthHint = 80;
        add.setLayoutData(gridData);
        add.setEnabled(rowAddable);
        add.addSelectionListener(new SelectionAdapter()
        {

            public void widgetSelected(SelectionEvent e)
            {
                tableViewer.add("-_-"); // suppose to be an empty string

                int selection = CompositeTableViewer.this.tableViewer.getTable().getItemCount();

                CompositeTableViewer.this.tableViewer.setSelection(
                        new StructuredSelection(tableViewer.getElementAt(selection - 1 + correctionSelection)), true);
                tableViewer.setSelection(new StructuredSelection(CompositeTableViewer.this.tableViewer.getElementAt(selection - 1)), true);


            }
        });

        // Create and configure the "Delete" button
        Button delete = new Button(parent, SWT.PUSH | SWT.CENTER);
        delete.setText("Delete");
        gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        gridData.widthHint = 80;
        delete.setLayoutData(gridData);

        delete.addSelectionListener(new SelectionAdapter()
        {
            // Remove the selection and refresh the view
            public void widgetSelected(SelectionEvent e)
            {
                Object[] dataTable = (Object[]) ((IStructuredSelection) tableViewer.getSelection()).toArray();
                if (dataTable != null)
                {
                    tableViewer.remove(dataTable);
                }
            }
        });

    }
}

编辑 问题是 ArraycontentProvider 不能用于 editable table。 而且我不应该使用列表作为模型。我换了一个清单。 我在评论我的新源代码

我导入了你的代码并做了一些修改,从我所看到的来看,有些地方似乎是错误的。

首先,ArraycontentProvider 在 java 文档中这样说:

this implementation of IStructuredContentProvider handles the case where the viewer input is an unchanging array or collection of elements

所以您的首要任务是编写自己的内容提供程序。这很重要,因为您需要更新您设置的输入,而此内容提供者可能不会为您做这件事。

其次,您需要添加列以使其可编辑。例如:

        TableViewerColumn c1 = new TableViewerColumn(tableViewer, tableViewerStyle);
        c1.setLabelProvider(new CellLabelProvider() {
            @Override
            public void update(ViewerCell cell) {
            }
        });
        c1.getColumn().setWidth(200);
        c1.setEditingSupport(new FirstNameEditingSupport(tableViewer));

这将使您的专栏可以使用专门的编辑器进行编辑。 (在那种情况下是文本。我从一个很好的教程中偷走了编辑器,你可以在这里找到它:

http://www.vogella.com/tutorials/EclipseJFaceTableAdvanced/article.html#jfaceeditor

现在通过这些更改,我设法解决了您的添加问题。 您将需要有一个可以更新的模型对象。就我而言,我创建了:

public static class TestObject {

    private String text;

    public TestObject(String text) {
        this.text = text;
    }
 }

这是必需的,因为在编辑器中,您必须使用编辑后的内容更新查看器的内容。

我没有做的是创建一个合适的 ContentProvider,所以在我的例子中我从不坚持我的更新。但是,添加有效,双击有效,编辑有效。

现在让您选择。 tableviewer 添加方法说:

This method should be called (by the content provider) when a single element has been added to the model, in order to cause the viewer to accurately reflect the model. This method only affects the viewer, not the model. Note that there is another method for efficiently processing the simultaneous addition of multiple elements.

这会返回给您的内容提供商。它需要处理内容已 added/edited/removed 的事实并相应地更新模型对象。

这应该可以让您现在开始。看看 Lars vogel 的教程,非常好,也很清楚该怎么做。让我知道是否还有更多问题,我会尝试创建一个更好的示例。

阿图尔

P.S.: Copy/pasting 你的代码没有为我编译。尝试为您的问题提供一个小型独立示例。这样就可以更轻松地针对它进行编码并为您提供更详细的指示。

这是我的新版本

package features.dataManagement.entity.table.ui;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

import features.dataManagement.entity.table.edit.StringEditingSupport;
import features.dataManagement.entity.table.model.RowStringContentProvider;
import features.dataManagement.entity.table.model.RowStringModel;

public class CompositeTableViewer extends Composite
{
    private TableViewer tableViewer;

    private List<String> columnNames;

    private List<RowStringModel> modelList;
    private Button addButton;

    public CompositeTableViewer(Composite parent, int style, List<String> columnNames, boolean rowAddable)
    {
        this(parent, style, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, columnNames, rowAddable);
    }

    public CompositeTableViewer(Composite parent, int style, int tableViewerStyle, List<String> columnNames, boolean rowAddable)
    {
        super(parent, style);
        modelList = new ArrayList<RowStringModel>();
        this.columnNames = columnNames;

        GridLayout layout = new GridLayout(3, false);
        layout.marginWidth = 4;
        this.setLayout(layout);

        Composite tableComposite = new Composite(this, SWT.NONE);
        // set 3 columns for the buttons
        tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));

        setTableViewer(new TableViewer(tableComposite, tableViewerStyle));
        TableViewerColumn tableViewerColumn = createColumn(tableComposite, tableViewer, 0);
        tableViewerColumn.setEditingSupport(new StringEditingSupport(tableViewer));
        TableColumnLayout tableColumnLayout = new TableColumnLayout();
        tableColumnLayout.setColumnData(tableViewerColumn.getColumn(), new ColumnWeightData(1, 100, true));
        tableComposite.setLayout(tableColumnLayout);

        tableViewer.setContentProvider(new RowStringContentProvider(tableViewer, modelList));

        final Table table = tableViewer.getTable();
        table.setLinesVisible(true);

        createButtons(this, rowAddable);

    }

    /*
     * this is specific to my project you can directly use a
     * List<RowStringModel> modelList
     */
    public void setInput(List<Object> dataList)
    {

        List<RowStringModel> dataStringList = new ArrayList<RowStringModel>();
        for (Object str : dataList)
        {
            if (str instanceof String)
                dataStringList.add(new RowStringModel((String) str));
        }
        modelList.addAll(dataStringList);
        this.tableViewer.setInput(modelList);
    }

    /*
     * this is specific to my project you can directly use a
     * List<RowStringModel> modelList
     */
    public List<Object> getInput()
    {
        List<Object> objectsInGui = new ArrayList<Object>();

        for (RowStringModel rowStr : modelList)
        {
            objectsInGui.add(rowStr.getContent());
        }
        return objectsInGui;
    }

    public void addButtonEnable(boolean enabled)
    {
        this.addButton.setEnabled(enabled);
    }

    // create the columns for the table
    private TableViewerColumn createColumn(final Composite parent, final TableViewer viewer, int colNumber)
    {
        TableViewerColumn col = createTableViewerColumn(this.columnNames.get(colNumber), colNumber);
        col.setLabelProvider(new ColumnLabelProvider()
        {
            @Override
            public String getText(Object element)
            {
                RowStringModel rsm = (RowStringModel) element;
                return rsm.getContent();
            }

            /* slight difference for the actual lines */
            @Override
            public Color getBackground(final Object element)
            {
                if (element instanceof RowStringModel)
                {
                    return new Color(Display.getDefault(), 245, 255, 250);
                }

                return super.getBackground(element);
            }
        });

        return col;

    }

    private TableViewerColumn createTableViewerColumn(String title, final int colNumber)
    {
        final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
        final TableColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setResizable(true);
        column.setMoveable(true);
        return viewerColumn;
    }

    /**
     * Add the "Add" and "Delete" buttons
     * 
     * @param parent
     *            the parent composite
     */
    private void createButtons(Composite parent, boolean rowAddable)
    {

        // Create and configure the "Add" button
        this.addButton = new Button(parent, SWT.PUSH | SWT.CENTER);
        this.addButton.setText("Add");

        GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        gridData.widthHint = 80;
        gridData.horizontalSpan = 1;
        this.addButton.setLayoutData(gridData);
        this.addButton.setEnabled(rowAddable);
        this.addButton.addSelectionListener(new SelectionAdapter()
        {
            public void widgetSelected(SelectionEvent e)
            {
                modelList.add(new RowStringModel(""));
                tableViewer.refresh();
                CompositeTableViewer.this.setFocus();
                int selection = CompositeTableViewer.this.tableViewer.getTable().getItemCount();
                CompositeTableViewer.this.tableViewer.setSelection(new StructuredSelection(tableViewer.getElementAt(selection - 1)), true);
            }
        });

        // Create and configure the "Delete" button
        Button delete = new Button(parent, SWT.PUSH | SWT.CENTER);
        delete.setText("Delete");
        gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        gridData.widthHint = 80;
        delete.setLayoutData(gridData);

        delete.addSelectionListener(new SelectionAdapter()
        {
            // Remove the selection and refresh the view
            public void widgetSelected(SelectionEvent e)
            {
                Object[] dataTable = (Object[]) ((IStructuredSelection) tableViewer.getSelection()).toArray();
                if (dataTable != null)
                {
                    for (Object data : dataTable)
                    {
                        modelList.remove(data);
                    }

                    tableViewer.refresh();
                }
            }
        });

    }

    public TableViewer getTableViewer()
    {
        return tableViewer;
    }

    public void setTableViewer(TableViewer tableViewer)
    {
        this.tableViewer = tableViewer;
    }

    public List<String> getColumnNames()
    {
        return columnNames;
    }

    public void setColumnNames(List<String> columnNames)
    {
        this.columnNames = columnNames;
    }

}

RowStringModel

package features.dataManagement.entity.table.model;

public class RowStringModel
{
    private String content;

    public RowStringModel(String content)
    {
        super();
        this.content = content;
    }

    public String getContent()
    {
        return content;
    }

    public void setContent(String content)
    {
        this.content = content;
    }

}

StringEditingSupport

package features.dataManagement.entity.table.edit;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;

import features.dataManagement.entity.table.model.RowStringModel;

public class StringEditingSupport extends EditingSupport
{

  private final TableViewer viewer;
  private final CellEditor editor;

    public StringEditingSupport(TableViewer viewer)
    {
    super(viewer);
    this.viewer = viewer;
    this.editor = new TextCellEditor(viewer.getTable());
  }

  @Override
  protected CellEditor getCellEditor(Object element) {
    return editor;
  }

  @Override
  protected boolean canEdit(Object element) {
    return true;
  }

  @Override
  protected Object getValue(Object element) {
        return ((RowStringModel) element).getContent();
  }

  @Override
  protected void setValue(Object element, Object userInputValue) {
      ((RowStringModel) element).setContent(String.valueOf(userInputValue));
    viewer.update(element, null);
  }
}

RowStringContentProvider

package features.dataManagement.entity.table.model;

import java.util.List;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;

public class RowStringContentProvider implements IStructuredContentProvider, IItemModelListViewer<RowStringModel>
{
    private TableViewer tableViewer;
    private List<RowStringModel> modelList;

    public RowStringContentProvider(TableViewer tableViewer, List<RowStringModel> modelList)
    {
        this.tableViewer = tableViewer;
        this.modelList = modelList;
    }

    public void inputChanged(Viewer v, Object oldInput, Object newInput)
    {
    }

    public void dispose()
    {
    }

    // Return the tasks as an array of Objects
    public Object[] getElements(Object parent)
    {
        return modelList.toArray();
    }


    public void addItemModel(RowStringModel itemModel)
    {
        tableViewer.add(itemModel);
    }

    @Override
    public void removeItemModel(RowStringModel itemModel)
    {
        tableViewer.remove(itemModel);

    }

    @Override
    public void updateItemModel(RowStringModel itemModel)
    {
        tableViewer.update(itemModel, null);

    }

}