我有时候(几次在3分钟左右,每100毫秒左右加点数)得到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()
的{{3}}点火并没有多说。 innerUpdate()
函数仅设置脏标志。由于崩溃在flagDataChange()
而不在其他地方,因此没有真正的下游原因。另外两个调用fireUpdate()
和super.fireDataChange()
,可以排除,因为如果FireUpdate()
或其下游的方法是原因,那么Eclipse会提到该函数,而不是{{ 1 {}在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;
}
思想?
答案 0 :(得分:1)
@AndyTurner关于显示器的问题是正确的。
我将代码更改为以下代码,运行了相当多的测试,这阻止了异常。
if (null != Display.getCurrent())
trace1Provider.addSample(oSample);
我将不得不调查空显示问题。
答案 1 :(得分:1)
在尝试从单独的Observer类更新dataprovider时,我也遇到了与当前版本(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();
}
}