2010-07-29 53 views
5

我使用org.eclipse.core.databinding框架来绑定SWT应用程序中的某些Text字段。我想补充的更新策略来验证数据,并在模型上设置的值,只有当用户点击保存按钮:数据绑定和验证TableViewer?

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

回答

6

你不需要使用的JFace数据绑定框架TableViewer。操纵结构化数据比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 */ 

} 

每个模型将成为TableItem并在TableItem(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

有一个完整的代码:http://pastie.org/1089932 – qrtt1 2010-08-13 07:16:54

+0

非常感谢这段代码。真的很有用! – flumins 2010-08-27 11:19:08

+8

...但为什么你想放弃数据绑定,并返回写许多样板代码? – vwegert 2010-12-29 20:38:19

2

使用ViewerSupport:

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

这似乎是一个很好的解决方案。但有没有办法使用验证器和转换器与表查看器与此? – Lii 2016-11-08 14:11:02

0

我同意qualidafial。

Snippet017TableViewerWithDerivedColumns来自jface.databinding片段就是一个完整的例子。

+0

该片段似乎不再可用。这是一个替代方案:http://wiki.eclipse.org/JFace_Data_Binding/Snippets#Viewers – paul 2013-12-19 13:07:16