在 TableViewer 中添加、编辑、删除元素

Adding, Editing, removing elements in TableViewer

我创建了一个包含两列的 TableViewer,我想在按下名为 "add" 的按钮后向其中添加行。按下按钮后,我想创建一个空行,第一列单元格将提供键入文本的选项,第二列单元格将提供在系统目录中浏览到 select 文件夹的选项。

我在单击 "add" 按钮后设法添加了一个空行,但是 returns 出现以下错误:发生错误。有关详细信息,请参阅错误日志。断言失败:第 0 列没有标签提供者 。 table 查看器的目的是在第一列单元格中插入一个字符串变量,在第二列单元格中插入一个路径。使用用户插入的数据,我想创建一个名为 ProjectDirectory 的 class 列表(这个 class 有两个 String 属性)。

我还设法用鼠标删除了我 select 的行,这很好用。

我是使用 Jface 和 SWT 的新手,我无法做到这一点。谁能帮帮我?

代码:

    Composite tableComposite = new Composite(pluginPathCreatedComposite, SWT.NONE);
    FormData tableCompositeData = new FormData();
    tableCompositeData.left = new FormAttachment(selectProjectPathLabel, 0, SWT.LEFT);
    tableCompositeData.top = new FormAttachment(selectProjectPathLabel, 40, SWT.TOP);
    tableCompositeData.right = new FormAttachment(selectProjectPathButton,-10,SWT.LEFT);
    tableCompositeData.bottom = new FormAttachment(createProjectConfigButton,-10,SWT.TOP);
    tableComposite.setLayoutData(tableCompositeData);

    //Create the tableviewer
    tableViewer = new TableViewer(tableComposite, SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
    Table table = tableViewer.getTable();
    tableViewer.getTable().setLinesVisible(true);
    tableViewer.getTable().setHeaderVisible(true);
    tableViewer.setColumnProperties(COLUMN_HEADINGS);

    //Create the tableViewer columns
    TableViewerColumn variable = new TableViewerColumn(tableViewer, SWT.NONE);
    variable.getColumn().setText(COLUMN_HEADINGS[0]);
    variable.getColumn().setResizable(false);

    TableViewerColumn path = new TableViewerColumn(tableViewer, SWT.NONE);
    path.getColumn().setText(COLUMN_HEADINGS[1]);
    path.getColumn().setResizable(false);

    TableColumnLayout tableLayout = new TableColumnLayout();
    tableComposite.setLayout(tableLayout);

    //Set the columns proportions
    tableLayout.setColumnData(path.getColumn(), new ColumnWeightData(50));
    tableLayout.setColumnData(variable.getColumn(), new ColumnWeightData(50));

    //Set the first row as TextCell (this doesn´t work)
    CellEditor[] editors = new CellEditor[2];
    editors[0] = new TextCellEditor(tableViewer.getTable());
    editors[1] = new TextCellEditor(tableViewer.getTable());
    tableViewer.setCellEditors(editors);

    //Add button
    Button addRow = new Button(pluginPathCreatedComposite, SWT.NONE);
    FormData addRowData = new FormData();
    addRowData.top = new FormAttachment(tableComposite,0,SWT.TOP);
    addRowData.left = new FormAttachment(selectProjectPathButton,0,SWT.LEFT);
    addRowData.right = new FormAttachment(selectProjectPathButton,0,SWT.RIGHT);
    addRow.setLayoutData(addRowData);
    addRow.setText("Add");

    addRow.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent e) {


            ProjectDirectory directory = new ProjectDirectory("A", "A");
            Table table = tableViewer.getTable();
            tableViewer.add(directory);
            table.setTopIndex(table.getItemCount());
            table.select(table.getItemCount() - 1);
        }
    });

    //Delete row
    Button deleteRow = new Button(pluginPathCreatedComposite, SWT.NONE);
    FormData deleteRowData = new FormData();
    deleteRowData.top = new FormAttachment(addRow,5,SWT.BOTTOM);
    deleteRowData.left = new FormAttachment(selectProjectPathButton,0,SWT.LEFT);
    deleteRowData.right = new FormAttachment(selectProjectPathButton,0,SWT.RIGHT);
    deleteRow.setLayoutData(deleteRowData);
    deleteRow.setText("Delete");

    deleteRow.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent e) {
            ISelection selection = tableViewer.getSelection();
            if (selection instanceof IStructuredSelection) {
                Iterator iterator = ((IStructuredSelection) selection).iterator();
                while (iterator.hasNext()) {
                    Object obj = iterator.next();
                    tableViewer.remove(obj);
                }
            }
        }
    });

图片:

UI

编辑:

我已经创建了一个内容提供程序来获取在代码中创建的列表的项目目录(我将来会更改它)。之后,我为每一列创建了一个标签提供程序,它显示了我想要的数据。

事实是,我想在按下添加按钮后在 table 中添加一个新行,并且我想让第一个单元格成为 TextCellEditor(第二个单元格将有一个事件来打开系统的目录路径作为图像之一,但在此之前我还想将其设为 TextCellEditor)。我已经定义了这两列将类似于 TextCell 编辑器,在按下添加按钮后我设法添加了一个空行,但我无法在其中键入文本。我还创建了一个 setCellModifier 来更新 table 查看器。我做错了什么?

代码

    Composite tableComposite = new Composite(pluginPathCreatedComposite, SWT.NONE);
    FormData tableCompositeData = new FormData();
    tableCompositeData.left = new FormAttachment(selectProjectPathLabel, 0, SWT.LEFT);
    tableCompositeData.top = new FormAttachment(selectProjectPathLabel, 40, SWT.TOP);
    tableCompositeData.right = new FormAttachment(selectProjectPathButton,-10,SWT.LEFT);
    tableCompositeData.bottom = new FormAttachment(createProjectConfigButton,-10,SWT.TOP);
    tableComposite.setLayoutData(tableCompositeData);

    tableViewer = new TableViewer(tableComposite, SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
    table = tableViewer.getTable();
    table.setLinesVisible(true);
    table.setHeaderVisible(true);
    tableViewer.setColumnProperties(COLUMN_HEADINGS);

    //Content provider
    tableViewer.setContentProvider(new ProjectConfigTableContentProvider());

    /*I have tried to use this instead of setting the label providers in the column definitions*/
   //tableViewer.setLabelProvider(new ProjectConfigTableLabelProvider());

    //Label provider setted in each column
    TableViewerColumn variable = new TableViewerColumn(tableViewer, SWT.NONE);
    variable.getColumn().setText(COLUMN_HEADINGS[0]);
    variable.getColumn().setResizable(false);
    variable.setLabelProvider(new ColumnLabelProvider(){
        public String getText(Object element) {
            if(element instanceof ProjectDirectory && element != null)
                return ((ProjectDirectory)element).getName();
            return super.getText(element);
        }
    });

    TableViewerColumn path = new TableViewerColumn(tableViewer, SWT.NONE);
    path.getColumn().setText(COLUMN_HEADINGS[1]);
    path.getColumn().setResizable(false);
    path.setLabelProvider(new ColumnLabelProvider(){
        public String getText(Object element) {
            if(element instanceof ProjectDirectory && element != null)
                return ((ProjectDirectory)element).getPath();
            return super.getText(element);
        }
    });

    //List created in code (will change this in the future)
    List<ProjectDirectory> b = new ArrayList<ProjectDirectory>();
    b.add(new ProjectDirectory("AA", "FF"));
    b.add(new ProjectDirectory("BB", "CC"));

    Project pro = new Project("A", "B", 2, b);

    //Input setted
    tableViewer.setInput(pro);

    TableColumnLayout tableLayout = new TableColumnLayout();
    tableComposite.setLayout(tableLayout);

    tableLayout.setColumnData(path.getColumn(), new ColumnWeightData(50));
    tableLayout.setColumnData(variable.getColumn(), new ColumnWeightData(50));

    CellEditor[] editors = new CellEditor[2];
    editors[0] = new TextCellEditor(table);
    editors[1] = new TextCellEditor(table);
    tableViewer.setCellEditors(editors);
    tableViewer.setCellModifier(new ProjectConfigTableCellModifier(COLUMN_HEADINGS,tableViewer));

    //addrow button
    Button addRow = new Button(pluginPathCreatedComposite, SWT.NONE);
    FormData addRowData = new FormData();
    addRowData.top = new FormAttachment(tableComposite,0,SWT.TOP);
    addRowData.left = new FormAttachment(selectProjectPathButton,0,SWT.LEFT);
    addRowData.right = new FormAttachment(selectProjectPathButton,0,SWT.RIGHT);
    addRow.setLayoutData(addRowData);
    addRow.setText("Add");

    addRow.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent e) {
            ProjectDirectory directory = new ProjectDirectory("", "");
            tableViewer.add(directory);
            table.setTopIndex(table.getItemCount());
            table.select(table.getItemCount() - 1);
            tableViewer.editElement(directory, 0);
        }
    });

我还创建了一个 labelProvider class 来避免像我所做的那样在每一列中设置标签提供程序,但它不起作用。代码是这样的:

@Override
    public String getColumnText(Object element, int columnIndex) {
    // TODO Auto-generated method stub
    ProjectDirectory projectDirectory = (ProjectDirectory) element;

    switch (columnIndex) {
    case 0:
        return projectDirectory.getName();
    case 1:
        return projectDirectory.getPath();
    }
    return null;
}

而对 class 的调用是这样的:

tableViewer.setLabelProvider(new ProjectConfigTableLabelProvider());

为什么只能将标签提供程序设置为列,而这种方式不起作用?

好的,我找到了解决问题的方法。

首先,我创建了一个组合,它将 table 包含在一个更大的组合中。

     private Composite createPluginPathCreatedComposite(){

        .................................

        //Label of bigger composite
        Text selectProjectPathText = new Text(pluginPathCreatedComposite, SWT.BORDER);
        selectProjectPathText.setEnabled(false);
        FormData selectProjectPathTextData = new FormData();
        selectProjectPathTextData.top = new FormAttachment(selectProjectPathLabel, 0, SWT.CENTER);
        selectProjectPathTextData.left = new FormAttachment(selectProjectPathLabel, 5,SWT.RIGHT);
        selectProjectPathTextData.right = new FormAttachment(100,-55);
        selectProjectPathText.setLayoutData(selectProjectPathTextData); 

        //Button to select a system directory
        Button selectProjectPathButton = new Button(pluginPathCreatedComposite, SWT.NONE);
        selectProjectPathButton.setText("Browse");
        FormData selectProjectPathButtonData = new FormData();
        selectProjectPathButtonData.top = new FormAttachment(selectProjectPathText, 0, SWT.TOP);
        selectProjectPathButtonData.left = new FormAttachment(selectProjectPathText, 5, SWT.RIGHT);
        selectProjectPathButtonData.right = new FormAttachment(100,-5);
        selectProjectPathButton.setLayoutData(selectProjectPathButtonData); 
        selectProjectPathButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                DirectoryDialog dialog = new DirectoryDialog(Display.getCurrent().getActiveShell());
                dialog.setFilterPath(""); // Windows specific
                selectProjectPathText.setText(dialog.open());
            }
        });

        //Create a composite for the table inside a bigger composite pluginPathCreatedComposite
        Composite tableComposite = new Composite(pluginPathCreatedComposite, SWT.NONE);
        FormData tableCompositeData = new FormData();
        tableCompositeData.left = new FormAttachment(selectProjectPathLabel, 0, SWT.LEFT);
        tableCompositeData.top = new FormAttachment(selectProjectPathLabel, 40, SWT.TOP);
        tableCompositeData.right = new FormAttachment(selectProjectPathButton,-10,SWT.LEFT);
        tableCompositeData.bottom = new FormAttachment(createProjectConfigButton,-10,SWT.TOP);
        tableComposite.setLayoutData(tableCompositeData);

        //Function to create the table. 
        createTable(tableComposite,selectProjectPathText);

        //add row to the tableviewer
        addRow.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                ProjectDirectory directory = new ProjectDirectory("Insert variable", "Click to add path");
                projectCompositeViewer.add(directory);
            }
        });

        //deleterow from the tableviewer
        Button deleteRow = new Button(pluginPathCreatedComposite, SWT.NONE);
        FormData deleteRowData = new FormData();
        deleteRowData.top = new FormAttachment(addRow,5,SWT.BOTTOM);
        deleteRowData.left = new FormAttachment(selectProjectPathButton,0,SWT.LEFT);
        deleteRowData.right = new FormAttachment(selectProjectPathButton,0,SWT.RIGHT);
        deleteRow.setLayoutData(deleteRowData);
        deleteRow.setText("Delete");

        deleteRow.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                ISelection selection = projectCompositeViewer.getSelection();
                if (selection instanceof IStructuredSelection) {
                    Iterator iterator = ((IStructuredSelection) selection).iterator();
                    while (iterator.hasNext()) {
                        Object obj = iterator.next();
                        projectCompositeViewer.remove(obj);
                    }
                }
            }
        });
        }

创建 table 函数,我已经将 table 组合和项目文件夹的路径作为参数传递:

    private void createTable(Composite tableComposite, Text selectProjectPathText){
        //Create the tableViewer and it´s columns
        projectCompositeViewer = new ProjectConfigViewer(tableComposite, selectProjectPathText,SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);

        //Create an input to display
        List<ProjectDirectory> b = new ArrayList<ProjectDirectory>();
        b.add(new ProjectDirectory("AA", "FF"));
        b.add(new ProjectDirectory("BB", "CC"));

        Project pro = new Project("A", "B", 2, b);
        projectCompositeViewer.setInput(pro);
    }

ProjectConfigViewer 代码:

public class ProjectConfigViewer extends TableViewer{

    public ProjectConfigViewer(Composite parent, Text selectProjectPathText,int style) 
    {
        super(parent, style);
        Table table = getTable();
        createColumns(parent, selectProjectPathText);
        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        //Specify Content provider
        setContentProvider(new ProjectConfigTableContentProvider());
    }

    //Create the columns, column´s label providers and editingsuport to specify how will each column cell be: text column, dialog column...
    private void createColumns(Composite parent,Text selectProjectPathText)
    {   
        String[] COLUMN_HEADINGS = {"Variable", "Path"};

        TableColumnLayout tableLayout = new TableColumnLayout();
        parent.setLayout(tableLayout);

        //Specify first column labelprovider and create it 
        TableViewerColumn variable = createTableViewerColumn(COLUMN_HEADINGS[0], 0);
        variable.getColumn().setResizable(false);
        variable.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof ProjectDirectory && element != null)
                    return ((ProjectDirectory)element).getName();
                return super.getText(element);
            }
        });

         //Specify second column labelprovider and create it
        TableViewerColumn path = createTableViewerColumn(COLUMN_HEADINGS[1], 1);
        path.getColumn().setResizable(false);
        path.setLabelProvider(new ColumnLabelProvider(){
            public String getText(Object element) {
                if(element instanceof ProjectDirectory && element != null)
                    return ((ProjectDirectory)element).getPath();
                return super.getText(element);
            }
        });

        //Spedify the dimensions of each column
        tableLayout.setColumnData(path.getColumn(), new ColumnWeightData(50));
        tableLayout.setColumnData(variable.getColumn(), new ColumnWeightData(50));

        //Specify setEditingSupport for each cell. First cell will be text, second will be a Dialog.
        variable.setEditingSupport(new ProjectConfigVariableEditingSupport(this));
        path.setEditingSupport(new ProjectConfigPathEditingSupport(this, selectProjectPathText));
    }

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

        return column;
    }
}

内容提供商:

public class ProjectConfigTableContentProvider implements IStructuredContentProvider {
    private List<ProjectDirectory> projectEntitiesList;

    @Override
    public Object[] getElements(Object arg0) {
        // TODO Auto-generated method stub
        if (arg0 instanceof Project){
            Project project = (Project) arg0; 
            if (project != null && project.getProjectDirectoriesList() != null){
                initializeTableProjectConfig(project);
                return projectEntitiesList.toArray();
            }
        }
        projectEntitiesList = new ArrayList<ProjectDirectory>();
        return projectEntitiesList.toArray();
    }

    private void initializeTableProjectConfig(Project project){
        try {
            List<ProjectDirectory> listProjectDirectory = new ArrayList<ProjectDirectory>();
            for (ProjectDirectory projectDirectory : project.getProjectDirectoriesList()) {
                if (projectDirectory != null) 
                    listProjectDirectory.add(projectDirectory);
            }
            this.projectEntitiesList = listProjectDirectory;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第一列的编辑支持:

public class ProjectConfigVariableEditingSupport extends EditingSupport {
    private TextCellEditor cellEditor;

    public ProjectConfigVariableEditingSupport(ColumnViewer viewer) {
        super(viewer);
        cellEditor = new TextCellEditor(((TableViewer)viewer).getTable());
    }
    protected CellEditor getCellEditor(Object element) {
        return cellEditor;
    }
    protected boolean canEdit(Object element) {
        return true;
    }
    protected Object getValue(Object element) {
        return ((ProjectDirectory) element).getName();
    }
    @Override
    protected void setValue(Object element, Object value) {
        ((ProjectDirectory) element).setName(String.valueOf(value));
        getViewer().update(element, null);
    }
}

第二列的编辑支持:

public class ProjectConfigPathEditingSupport extends EditingSupport{
    private DialogCellEditor  cellEditor;

    //Pass selecProjectPathText of the bigger composite to brose from that directory
    public ProjectConfigPathEditingSupport(ColumnViewer viewer, Text selectProjectPathText) {
        super(viewer);
        cellEditor = new DialogCellEditor(((TableViewer)viewer).getTable()) {
            @Override
            protected Object openDialogBox(Control cellEditorWindow) {
                // TODO Auto-generated method stub
                DirectoryDialog dialog = new DirectoryDialog(cellEditorWindow.getShell());
                dialog.setText("Browse");
                dialog.setFilterPath(selectProjectPathText.getText()); // Windows specific
                return  dialog.open();
            }
        };
    }
    protected CellEditor getCellEditor(Object element) {
        return cellEditor;
    }
    protected boolean canEdit(Object element) {
        return true;
    }
    protected Object getValue(Object element) {
        return ((ProjectDirectory) element).getPath();
    }
    protected void setValue(Object element, Object value) 
    {
        ((ProjectDirectory) element).setPath(String.valueOf(value));
        getViewer().update(element, null);
    }
}

型号类:

public class Project {
    private String name;
    private String path;
    private Integer quantity;
    private List<ProjectDirectory> projectDirectoryList;

    //Constructor
    public Project(String name, String path, Integer quantity, List<ProjectDirectory> projectDirectoriesList) {
        super();
        this.name = name;
        this.path = path;
        this.quantity = quantity;
        this.projectDirectoryList = projectDirectoriesList;
    }
    //GETTERS AND SETTERS
}

public class ProjectDirectory {
    private String name;
    private String path;

    //Constructor
    public ProjectDirectory(String name, String path) {
        super();
        this.path = path;
        this.name = name;
    }

    //Getters & setters

照片: Explanation of use

导致此问题的最简单原因之一是在创建列之前添加了标签提供程序。始终注意在之后添加标签提供程序!