首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NatTable IColumnAccessor.setDataValue被调用两次

NatTable IColumnAccessor.setDataValue被调用两次
EN

Stack Overflow用户
提问于 2015-08-07 13:05:25
回答 1查看 461关注 0票数 0

上下文

我已经实现了一个NatTable (v1.1.0.201405012245) --请考虑以下简化示例:

代码语言:javascript
复制
package testproject;

import java.util.ArrayList;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.EditableRule;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditBindings;
import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration;
import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.selection.config.DefaultSelectionStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class ViewPart1 extends ViewPart
{
  @Override
  public void createPartControl(final Composite parent)
  {
    final ArrayList<String> list = new ArrayList<>();
    list.add("one");
    list.add("two");
    list.add("three");

    final IColumnAccessor<String> columnAccessor = new IColumnAccessor<String>()
    {
      @Override
      public void setDataValue(final String rowObject, final int columnIndex, final Object newValue)
      {
        if (!(newValue instanceof String) || ((String) newValue).contains("x"))
        {
          MessageDialog.openError(getSite().getShell(), "Error", "Invalid Input");
          return;
        }
        list.set(list.indexOf(rowObject), (String) newValue);
      }

      @Override
      public Object getDataValue(final String rowObject, final int columnIndex)
      {
        return rowObject;
      }

      @Override
      public int getColumnCount()
      {
        return 1;
      }
    };

    final IDataProvider dataProvider = new ListDataProvider<>(list, columnAccessor);
    final DataLayer dataLayer = new DataLayer(dataProvider);
    final SelectionLayer selectionLayer = new SelectionLayer(dataLayer);
    final ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

    final NatTable table = new NatTable(parent, viewportLayer, false);
    GridDataFactory.fillDefaults().grab(true, true).applyTo(table);

    viewportLayer.addConfiguration(new DefaultEditConfiguration());
    viewportLayer.addConfiguration(new DefaultEditBindings());
    viewportLayer.setRegionName(GridRegion.BODY);

    viewportLayer.setConfigLabelAccumulator(new IConfigLabelAccumulator()
    {
      @Override
      public void accumulateConfigLabels(final LabelStack configLabels, final int columnPosition, final int rowPosition)
      {
        configLabels.addLabel("myLabel");
      }
    });

    table.setConfigRegistry(new ConfigRegistry());
    table.addConfiguration(new DefaultNatTableStyleConfiguration());
    table.addConfiguration(new DefaultSelectionStyleConfiguration());
    table.addConfiguration(new AbstractRegistryConfiguration()
    {
      @Override
      public void configureRegistry(final IConfigRegistry registry)
      {
        registry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new TextCellEditor(true), DisplayMode.NORMAL, "myLabel");
        registry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE, EditableRule.ALWAYS_EDITABLE, DisplayMode.NORMAL, "myLabel");
      }
    });
    table.configure();
  }

  @Override
  public void setFocus()
  {
  }
}

当然,这不是真正的代码,但是我的问题也可以用这个代码来演示。

重要的是,在我的实际项目中,当用户修改一个值时,我需要更新一个模型(包括一个复杂的依赖树),如果它失败了(例如,在数值计算中,更改会导致除法为零),我需要显示一个错误(并恢复到以前的值)。

为了显示我的核心问题,在这里显示的代码中,我检查IColumnAccessor#setDataValue中的一个简单条件(输入包含一个'x'),并相应地显示错误。

问题

我的实际问题是,如果您在TextCellEditor中输入x,错误对话框会弹出两次(按顺序--即当我单击第一个对话框确定时,第二个对话框将显示)。

分析

我的分析表明,原因是setDataValue被调用了两次:

  1. 因为按下了ENTER键- Stacktrace
代码语言:javascript
复制
- `TextCellEditor(AbstractCellEditor).commit(SelectionLayer$MoveDirectionEnum, boolean) line: 331`
- `TextCellEditor(AbstractCellEditor).commit(SelectionLayer$MoveDirectionEnum) line: 326`
- `TextCellEditor$1.keyPressed(KeyEvent) line: 246`

  1. 因为TextCellEditor失去了焦点-堆栈跟踪
代码语言:javascript
复制
- `TextCellEditor(AbstractCellEditor).commit(SelectionLayer$MoveDirectionEnum, boolean, boolean) line: 341`
- `TextCellEditor(AbstractCellEditor).commit(SelectionLayer$MoveDirectionEnum, boolean) line: 331`
- `AbstractCellEditor$InlineFocusListener.focusLost(FocusEvent) line: 462`

因此,我的主要问题是:我如何预防(或至少检测到)第二个事件?

EN

回答 1

Stack Overflow用户

发布于 2015-08-07 15:26:09

您的实现的问题是,您正在IColumnAccessor中执行一个转换,并打开一个对话框通知用户错误。但是,由于使用了各种用例,这并不是使用NatTable的方法。

如果需要执行转换和/或验证,则应该注册适当的IDisplayConverter和IDataValidator。由于您需要一个字符串,所以不需要注册不同的转换器,因为通过DefaultEditConfiguration注册的默认转换器已经在注册了。所以,您需要的是一个IDataValidator,它检查值x,在这种情况下抛出一个ValidationFailedException。如果将DialogErrorHandling注册为验证错误处理程序,则带有异常消息的错误将显示在对话框中。不打开对话框两次的检查是在内部完成的。

这在(目前较小的)文档http://www.eclipse.org/nattable/documentation.php?page=editing中得到了解释。

顺便说一句,我建议更新最新的NatTable版本1.3.0,因为它还包含几个BTW。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31878482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档