2010-07-29 36 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