2010-07-29 19 views
5

Tôi sử dụng khung org.eclipse.core.databinding để ràng buộc một số trường Text trong một ứng dụng SWT. Tôi thêm một chiến lược cập nhật để xác nhận các dữ liệu và thiết lập giá trị trên mô hình chỉ khi người dùng nhấn vào nút tiết kiệm:Databind và xác nhận một 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); 

Đoạn mã này hoạt động thực sự tốt.

Nhưng làm cách nào tôi có thể thực hiện tương tự trên TableViewer?

Tôi muốn nó làm việc để khi tôi thêm một cái gì đó trong IHM, mô hình ở không thay đổi cho đến khi tôi gọi getBindingContext().updateModels();

Trả lời

6

Bạn không cần phải sử dụng Databinding Khung JFace trong TableViewer. Thao tác với dữ liệu có cấu trúc đơn giản hơn các điều khiển SWT, chẳng hạn như TableViewer, ListViewerTreeViewer. Bạn có thể sử dụng những người xem trong cùng một cách:

  • tạo xem
  • cung cấp nội dung bộ
  • bộ cung cấp nhãn (đề nghị)
  • bộ lọc (không bắt buộc)
  • bộ sorter (không bắt buộc)

Sau khi trình xem được tạo, chỉ cần gọi viewer.setInput(data) để đặt tất cả mọi thứ cho người xem của bạn.

Có một danh sách các mô hình:

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

Sự kỳ diệu xảy ra trong các nhà cung cấp nội dung:

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 */ 

} 

Mỗi mô hình sẽ trở thành một TableItem và mô hình trong TableItem(item.getData()).

Tuy nhiên, một bảng gồm nhiều cột, bạn cần LabelProvider để giúp bạn lập bản đồ tài sản của mô hình để các 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 ""; 
    } 
} 

Các tuyên truyền các mô hình để người xem dễ dàng. Nếu bạn sẽ truyền người xem đến mô hình bị ràng buộc, sử dụng CellEditor cũng đơn giản. Để sử dụng CellEditor, bạn cần thiết lập các thuộc tính cột, biên tập viên tế bào và sửa đổi tế bào để TableViewer:

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

Các CellModifier thích này:

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

Mọi thứ đều đơn giản nhưng có rất nhiều bước để làm cho tất cả cùng với nhau.

+1

Có một mã hoàn chỉnh: http://pastie.org/1089932 – qrtt1

+0

Cảm ơn rất nhiều vì mã này. Thực sự hữu ích! – flumins

+8

... nhưng tại sao bạn muốn từ bỏ dữ liệu và quay lại viết nhiều mã soạn sẵn? – vwegert

2

Sử dụng ViewerSupport:

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

Điều này có vẻ như một giải pháp tốt. Nhưng có cách nào để sử dụng trình duyệt tính hợp lệ và trình chuyển đổi với trình xem bảng với điều này không? – Lii

0

tôi đồng ý với qualidafial.

Snippet017TableViewerWithDerivedColumns từ đoạn mã jface.databinding là ví dụ đầy đủ về điều này.

+0

Đoạn mã dường như không còn nữa. Đây là một thay thế: http://wiki.eclipse.org/JFace_Data_Binding/Snippets#Viewers – paul

Các vấn đề liên quan