【问题标题】:Nattable add row commandNattable 添加行命令
【发布时间】:2019-04-04 11:09:21
【问题描述】:

一个 E4 RCP 应用程序由几个 nattables 组成。

Material nattable 允许创建新的用户定义的材料。

Material nattable 包括过滤列。

EventList<AncolabMaterial> eventList = GlazedLists.eventList(input_values_list);
TransformedList<?, ?> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
SortedList<?> sortedList = new SortedList<>(rowObjectsGlazedList, null);
this.filterList = new FilterList<AncolabMaterial>((EventList<AncolabMaterial>) sortedList);
this.bodyDataProvider = new ListDataProvider<AncolabMaterial>(this.filterList, columnPropertyAccessor);
DataLayer bodyDataLayer = new DataLayer(getBodyDataProvider());
bodyDataLayer.registerCommandHandler(new DeleteRowCommandHandler<>(((ListDataProvider<AncolabMaterial>) bodyDataProvider).getList()));
bodyDataLayer.registerCommandHandler(new AddRowCommandHandler(((ListDataProvider<Object>) bodyDataProvider).getList()));
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<?> glazedListsEventLayer =
        new GlazedListsEventLayer<AncolabMaterial>(bodyDataLayer, this.filterList);
this.selectionLayer = new SelectionLayer(glazedListsEventLayer, false);
selectionLayer.addConfiguration(new DefaultRowSelectionLayerConfiguration());
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
/...

这是通过创建一个命令和命令处理程序来处理添加事件来完成的,如 链接 (Delete rows from Nattable)

  1. 创建添加行的命令
    public class AddRowCommand extends AbstractRowCommand {
        private Object item;
        public AddRowCommand(ILayer layer, Object item) {
            super(layer, 0);
            this.setItem(item);
        }
        protected AddRowCommand(AddRowCommand command) {
           super(command);
        }
        @Override
        public ILayerCommand cloneCommand() {
            return new AddRowCommand(this);
        }
        public Object getItem() {
            return this.item;
        }
        private void setItem(Object item) {
            this.item = item;
        }
    }
  1. 创建命令处理程序
    public class AddRowCommandHandler implements ILayerCommandHandler<AddRowCommand> {
        private List<Object> bodyData;
        public AddRowCommandHandler(List<Object> bodyData) {
            this.bodyData = bodyData;
        }
        @Override
        public Class<AddRowCommand> getCommandClass() {
            return AddRowCommand.class;
        }
        @Override
        public boolean doCommand(ILayer targetLayer,  AddRowCommand command) {
                this.bodyData.add(0, (AncolabMaterial)command.getItem() );
                targetLayer.fireLayerEvent(new RowInsertEvent(targetLayer, command.getRowPosition()));
                return true;
        }  
     }
  1. 将命令处理程序注册到主体 DataLayer
    bodyDataLayer.registerCommandHandler(new DeleteRowCommandHandler<>(((ListDataProvider<AncolabMaterial>) bodyDataProvider).getList()));
    bodyDataLayer.registerCommandHandler(new AddRowCommandHandler(((ListDataProvider<Object>) bodyDataProvider).getList()));

注意:删除行的命令处理程序工作正常

  1. 将菜单项添加到触发命令的菜单配置中
    //At SWT Button mouseUp event:
    AddUserMaterialDialog dialog = new AddUserMaterialDialog(shell);
    dialog.create();
    if (dialog.open() == Window.OK) {
        AncolabMaterial matToAdd = dialog.getUserMaterial();
        natTableMaterials.doCommand(new AddRowCommand(natTableMaterials, matToAdd));
    }

创建新材质后,材质列表更新,但渲染表格时抛出以下错误并且表格无法正确渲染:

Error while painting table
java.lang.RuntimeException: java.lang.NullPointerException
at org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor.getDataValue(ReflectiveColumnPropertyAccessor.java:74)
at org.eclipse.nebula.widgets.nattable.data.ListDataProvider.getDataValue(ListDataProvider.java:51)
at org.eclipse.nebula.widgets.nattable.layer.DataLayer.getDataValue(DataLayer.java:164)
at org.eclipse.nebula.widgets.nattable.layer.DataLayer.getDataValueByPosition(DataLayer.java:447)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:351)
at org.eclipse.nebula.widgets.nattable.layer.AbstractIndexLayerTransform.getDataValueByPosition(AbstractIndexLayerTransform.java:358)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:351)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:351)
at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer.getDataValueByPosition(CompositeLayer.java:617)
at org.eclipse.nebula.widgets.nattable.layer.cell.AbstractLayerCell.getDataValue(AbstractLayerCell.java:64)
at org.eclipse.nebula.widgets.nattable.layer.cell.CellDisplayConversionUtils.convertDataType(CellDisplayConversionUtils.java:21)
at org.eclipse.nebula.widgets.nattable.painter.cell.AbstractTextPainter.convertDataType(AbstractTextPainter.java:188)
at org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter.paintCell(TextPainter.java:157)
at org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper.paintCell(CellPainterWrapper.java:67)
at org.eclipse.nebula.widgets.nattable.painter.cell.decorator.LineBorderDecorator.paintCell(LineBorderDecorator.java:76)
at org.eclipse.nebula.widgets.nattable.painter.layer.CellLayerPainter.paintCell(CellLayerPainter.java:216)
at org.eclipse.nebula.widgets.nattable.painter.layer.CellLayerPainter.paintLayer(CellLayerPainter.java:86)
at org.eclipse.nebula.widgets.nattable.painter.layer.GridLineCellLayerPainter.paintLayer(GridLineCellLayerPainter.java:141)
at org.eclipse.nebula.widgets.nattable.selection.SelectionLayerPainter.paintLayer(SelectionLayerPainter.java:111)
at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer$CompositeLayerPainter.paintLayer(CompositeLayer.java:1055)
at org.eclipse.nebula.widgets.nattable.painter.layer.NatLayerPainter.paintLayer(NatLayerPainter.java:54)
at org.eclipse.nebula.widgets.nattable.NatTable.paintNatTable(NatTable.java:507)
at org.eclipse.nebula.widgets.nattable.NatTable.paintControl(NatTable.java:502)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:231)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4118)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1052)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1076)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
at org.eclipse.swt.widgets.Composite.WM_PAINT(Composite.java:1561)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4822)
at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:345)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:4765)
at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2303)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3532)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1170)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1059)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:162)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:656)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:592)
at org.eclipse.equinox.launcher.Main.run(Main.java:1498)
at org.eclipse.equinox.launcher.Main.main(Main.java:1471)
Caused by: java.lang.NullPointerException
at org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor.getPropertyDescriptor(ReflectiveColumnPropertyAccessor.java:107)
at org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor.getDataValue(ReflectiveColumnPropertyAccessor.java:69)
... 53 more

【问题讨论】:

  • 没有调试很难说。但我会假设应该添加到基础列表的对象为空。
  • 在上一步中,AncolabMaterial mattToAdd 不为空
  • 命令本身呢?那么在第 2 步的命令处理程序内部呢?
  • 好的,当我尝试打印 'System.out.println(((AncolabMaterial)command.getItem()).getName());'时,命令处理程序返回 null

标签: eclipse-rcp nattable


【解决方案1】:

NPE 来自ReflectiveColumnPropertyAccessor,当尝试通过对空对象的反射访问 getter 方法时。我想您遇到了列表转换的问题。如果我正确阅读了您的代码,您将在命令处理程序中使用FilterListFilterList 上的添加操作尚未或尚未传播到基础输入列表。我建议使用EventList 而不是FilterList 注册命令处理程序。

【讨论】:

  • 如果我为eventList注册命令处理程序:bodyDataLayer.registerCommandHandler(new AddRowCommandHandler(eventList));获得NPE。此外,如果使用FilterList 作为bodyDataProvider 的列表的其他列表,则再次获得NPE。我想我不知道如何将命令注册到 List...
  • 我只是说为命令处理程序注册EventList。我没说要改变身体数据提供者。
猜你喜欢
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 2011-08-25
相关资源
最近更新 更多