数据绑定和验证 TableViewer?

发布于 2024-09-11 14:55:19 字数 754 浏览 5 评论 0原文

我使用 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();

I use the org.eclipse.core.databinding framework to bind some Text fields in an SWT application. I add an update strategy to validate the data and to set the value on the model only when the user click on the save button:

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

This piece of code works really well.

But how can I do the same on a TableViewer?

I want it to work so that when I add something in the IHM, the model stay unchanged until I call getBindingContext().updateModels();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

披肩女神 2024-09-18 14:55:19

您不需要在 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 */

}

每个模型将成为一个 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();
        }
    }
}

一切都很简单,但需要很多步骤才能将所有内容组合在一起。

You do not need use the JFace Databinding Framework in TableViewer. Manipulation the structured data is simpler then SWT controls, such TableViewer, ListViewer and TreeViewer. You can use those viewer in the same way:

  • create viewer
  • set content provider
  • set label provider (suggested)
  • set filter (optional)
  • set sorter (optional)

After the viewer created, just invoke viewer.setInput(data) to put all the things to your viewer.

There are a list of model:

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

The magic happens in the content provider:

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

}

Each model will become a TableItem and the model in the TableItem(item.getData()).

However, a table composed by many columns, you need the LabelProvider to help you mapping the property of model to the 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 "";
    }
}

The propagation of models to viewer is easy. If you will propagate viewer to the binded model, using the CellEditor is simple as well.
To use CellEditor, you need set the column properties, cell editors and cell modifier to TableViewer:

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

The CellModifier likes this:

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

Everything is simple but there are many steps to make all together.

未央 2024-09-18 14:55:19

使用查看器支持:

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

Use ViewerSupport:

TableViewer tableViewer = ...
IObservableList tableElements = ...
IValueProperty[] columnProperties = ...
ViewerSupport.bind(tableViewer, tableElements, columnProperties);
梦魇绽荼蘼 2024-09-18 14:55:19

我同意资格。

jface.databinding 片段中的 Snippet017TableViewerWithDerivedColumns 就是一个完整的示例。

i agree with qualidafial.

Snippet017TableViewerWithDerivedColumns from the jface.databinding snippets is a full example of this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文