Databind并验证TableViewer?

时间:2010-07-29 15:18:06

标签: java data-binding jface

我使用org.eclipse.core.databinding框架绑定SWT应用程序中的一些Text字段。我添加了一个更新策略来验证数据,并仅在用户单击保存按钮时在模型上设置值:

    UpdateValueStrategy toModel = new UpdateValueStrategy(UpdateValueStrategy.POLICY_CONVERT);
    if (validator != null) {
        toModel.setAfterGetValidator(validator);
    }

    UpdateValueStrategy fromModel = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);

    binding = bindingContext.bindValue(SWTObservables.observeText(this, SWT.Modify),
                    BeansObservables.observeValue(pVO, propertyName), toModel, fromModel);

这段代码效果很好。

但我怎样才能在TableViewer上做同样的事情?

我希望它能够工作,这样当我在IHM中添加内容时,模型保持不变,直到我调用getBindingContext().updateModels();

3 个答案:

答案 0 :(得分:7)

您不需要在TableViewer中使用JFace数据绑定框架。操纵结构化数据比SWT控制更简单,例如TableViewerListViewerTreeViewer。您可以以相同的方式使用这些查看器:

  • 创建查看器
  • 设置内容提供商
  • 设置标签提供者(建议)
  • 设置过滤器(可选)
  • 设置分拣机(可选)

查看器创建后,只需调用viewer.setInput(data)即可将所有内容放入查看器中。

有一个型号列表:

TableViewer tableViewer = new TableViewer(parent); 

Table table = tableViewer.getTable(); 
table.setHeaderVisible(true);      
table.setLinesVisible(true);`

for (int i = 0; i < COLUMN_NAMES.length; i++) {
    TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
    tableColumn.setText(COLUMN_NAMES[i]);
    tableColumn.setWidth(COLUMN_WIDTHS[i]);
}

tableViewer.setContentProvider(new ModelContentProvider());
tableViewer.setLabelProvider(new ModelLabelProvider());
tableViewer.setInput(models);

神奇发生在内容提供商中:

class ModelContentProvider implements IStructuredContentProvider {

    @SuppressWarnings("unchecked")
    @Override
    public Object[] getElements(Object inputElement) {
        // The inputElement comes from view.setInput()
        if (inputElement instanceof List) {
            List models = (List) inputElement;
            return models.toArray();
        }
        return new Object[0];
    }

/* ... other methods */

}

每个模型将成为TableItemTableItem(item.getData())中的模型。

但是,由许多列组成的表格,您需要LabelProvider来帮助您将模型的属性映射到TableItem

class ModelLabelProvider extends LabelProvider implements
        ITableLabelProvider {

    @Override
    public Image getColumnImage(Object element, int columnIndex) {
        // no image to show
        return null;
    }

    @Override
    public String getColumnText(Object element, int columnIndex) {
        // each element comes from the ContentProvider.getElements(Object)
        if (!(element instanceof Model)) {
            return "";
        }
        Model model = (Model) element;
        switch (columnIndex) {
        case 0:
            return model.getFoo();
        case 1:
            return model.getBar();
        default:
            break;
        }
        return "";
    }
}

模型向观众的传播很容易。如果您将查看器传播到绑定模型,使用CellEditor也很简单。 要使用CellEditor,您需要将列属性,单元格编辑器和单元格修改器设置为TableViewer

tableViewer.setColumnProperties(COLUMNS_PROPERTIES);
tableViewer.setCellEditors(new CellEditor[] {
        new TextCellEditor(table), new TextCellEditor(table) });
tableViewer.setCellModifier(new ModelCellModifier(tableViewer));

CellModifier喜欢这个:

class ModelCellModifier implements ICellModifier {
    TableViewer viewer;

    public ModelCellModifier(TableViewer viewer) {
        this.viewer = viewer;
    }

    @Override
    public boolean canModify(Object element, String property) {
        // property is defined by viewer.setColumnProperties()
        // allow the FOO column can be modified.
        return "foo_prop".equals(property);
    }

    @Override
    public Object getValue(Object element, String property) {
        if ("foo_prop".equals(property)) {
            return ((Model) element).getFoo();
        }
        if ("bar_prop".equals(property)) {
            return ((Model) element).getBar();
        }
        return "";
    }

    @Override
    public void modify(Object element, String property, Object value) {
        if ("foo_prop".equals(property)) {
            TableItem item = (TableItem) element;
            ((Model) item.getData()).setFoo("" + value);

            // refresh the viewer to show the changes to our user.
            viewer.refresh();
        }
    }
}

一切都很简单,但有很多步骤可以让所有人聚在一起。

答案 1 :(得分:2)

使用ViewerSupport:

TableViewer tableViewer = ...
IObservableList tableElements = ...
IValueProperty[] columnProperties = ...
ViewerSupport.bind(tableViewer, tableElements, columnProperties);

答案 2 :(得分:0)

我同意qualidafial。

来自Snippet017TableViewerWithDerivedColumns代码段的

jface.databinding就是一个完整的例子。