0

我有时(在每 100 毫秒左右添加点数的 3 分钟情节上几次)收到 a NullPointerException,但我没有看到任何可能的原因。

java.lang.NullPointerException
    at org.eclipse.nebula.visualization.xygraph.dataprovider.CircularBufferDataProvider.fireDataChange(CircularBufferDataProvider.java:474)
    at org.eclipse.nebula.visualization.xygraph.dataprovider.CircularBufferDataProvider.addSample(CircularBufferDataProvider.java:155)
    at myProject.XYGraphTransfer.addPoint(XYGraphTransfer.java:432)

这是代码示例。

trace1Provider = new CircularBufferDataProvider(true);
trace1Provider.setBufferSize(XYGraphTransfer.Graph_BufferEntries);
trace1Provider.setUpdateDelay(100);
Trace trace1 = new Trace("Time Plot", xyGraph.primaryXAxis, xyGraph.primaryYAxis, trace1Provider);
...
Long timeCurrent = Calendar.getInstance().getTimeInMillis();
Sample oSample = new Sample(timeCurrent, valueBase);
trace1Provider.addSample(oSample);

例外总是trace1Provider.addSample(oSample)在线。

oSample永远不可能null,所以这种可能性是不可能的。

线索是实际的错误线,

at org.eclipse.nebula.visualization.xygraph.dataprovider.CircularBufferDataProvider.fireDataChange(CircularBufferDataProvider.java:474)

那对我没有多大帮助,因为火源不多fireDataChange()说了。该innerUpdate()函数仅设置一个脏标志。由于坠机发生在flagDataChange()而不是其他地方,因此没有真正的下游原因。其他两个调用fireUpdate()super.fireDataChange(),一个可以消除,因为如果原因FireUpdate()或下游的方法是原因,那么 Eclipse 会提到该函数,而不是fireDataChange()CircularBufferDataProvider类中。

@Override
protected synchronized void fireDataChange()
{
    if (updateDelay > 0)
    {
        innerUpdate();
        if (!duringDelay)
        {
            Display.getCurrent().timerExec(updateDelay, fireUpdate);
            duringDelay = true;
        }
    } else
        super.fireDataChange();
}

@Override
protected void innerUpdate()
{
    dataRangedirty = true;
}

我的想法是某种争用,但只有一个函数可以向图形添加点,那就是在应用程序线程中。该图也存在于应用程序线程上。

更新:完整的堆栈跟踪。

java.lang.NullPointerException
    at org.eclipse.nebula.visualization.xygraph.dataprovider.CircularBufferDataProvider.fireDataChange(CircularBufferDataProvider.java:474)
    at org.eclipse.nebula.visualization.xygraph.dataprovider.CircularBufferDataProvider.addSample(CircularBufferDataProvider.java:155)
    at prjNetAccelerator.XYGraphTransfer.addPoint(XYGraphTransfer.java:432)
    at prjNetAccelerator.AppGraphTransfer.addPoint(AppGraphTransfer.java:283)
    at prjNetAccelerator.AppGraphTransfer.pushPoint(AppGraphTransfer.java:187)
    at prjNetAccelerator.HtsLink.getStatusGui(HtsLink.java:456)
    at prjNetAccelerator.HtsLink.getStatusBasic(HtsLink.java:568)
    at prjNetAccelerator.ToolsTreeFolders.fetchFiles(ToolsTreeFolders.java:1351)
    at prjNetAccelerator.TimerFilesFetch.run(TimerFilesFetch.java:81)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)

想法?

4

2 回答 2

1

@AndyTurner 关于显示问题是正确的。

我将代码更改为以下代码,运行了很多测试,并且防止了异常。

if (null != Display.getCurrent())
    trace1Provider.addSample(oSample);

我将不得不调查空显示问题。

于 2015-10-23T23:49:36.623 回答
1

在尝试从单独的 Observer 类更新数据提供者时,我也遇到了与当前版本(2.1.0.201808161734)相同的问题。对我有用的是从小部件所在的 Composite 中获取显示,并将 timerExec 包装在 asyncExec 中:

MyCircularBufferDataProvider extends AbstractDataProvider {...

    @Override
    protected synchronized void fireDataChange() {
        if (updateDelay > 0) {
            if (!duringDelay) {
                parentComposite.getDisplay().asyncExec(
                        ()-> parentComposite.getDisplay().timerExec(updateDelay, fireUpdate));
                duringDelay = true;
            }
        } else
            super.fireDataChange();
    }
}
于 2018-09-23T22:22:24.587 回答