我正在使用MASON库来运行一个简单的基于代理的模型。
根据规范,我打算通过在Portrayal中双击这样的代理来访问代理人的检查员。
但是,当我这样做时,我收到以下控制台错误:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sim.display.Display2D.createInspectors(Display2D.java:1737)
at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)
我去了Display2D.java:1737找到:
public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
{
Bag inspectors = new Bag();
Bag names = new Bag();
Bag[] hitObjects = objectsHitBy(rect);
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
simulation.controller.setInspectors(inspectors,names); //1737
}
但是,这是一个库文件,所以我不熟悉它。
有什么建议吗?
图书馆:cs.gmu.edu/~eclab/projects/mason /
更新
好的,它变得有趣......
我对检查员和名字的toString方法做了回音,返回:
insepectors sim.util.Bag@1b2202a names sim.util.Bag@16b334d
好的,所以他们是包包,一种收藏品。是时候搞定了......
insepectors 1 names 1
好,他们不是空的。
让我们按照错误堆栈
下一位:
at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)
// add mouse listener for the inspectors
insideDisplay.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (handleMouseEvent(e)) { repaint(); return; }
else
{
// we only care about mouse button 1. Perhaps in the future we may eliminate some key modifiers as well
int modifiers = e.getModifiers();
if ((modifiers & e.BUTTON1_MASK) == e.BUTTON1_MASK)
{
final Point point = e.getPoint();
if( e.getClickCount() == 2 )
1392-> createInspectors( new Rectangle2D.Double( point.x, point.y, 1, 1 ),
Display2D.this.simulation );
if (e.getClickCount() == 1 || e.getClickCount() == 2) // in both situations
performSelection( new Rectangle2D.Double( point.x, point.y, 1, 1 ));
repaint();
}
}
}
好的,错误显然在CreateInspectors方法中:
public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
{
Bag inspectors = new Bag();
Bag names = new Bag();
Bag[] hitObjects = objectsHitBy(rect);
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
System.out.println("insepectors " + inspectors.size() + " names " + names.size());
simulation.controller.setInspectors(inspectors,names);
}
我做的第一件事:
System.out.println(rect.getCenterX() + " " + rect.getCenterY());
这给了我646.5 659.5。似乎是坐标有意义。
接下来我想看一下hitObjects:
System.out.println(hitObjects.length);
返回2.所以我在那个坐标处有两个代理。
我认为NPE就在这里:
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
外环看起来很好,但我遇到内部问题。建议?
答案 0 :(得分:1)
我实际上会写你如何通过你给出的图书馆代码来推理,因为你听起来很有能力。
您找到了代码。这是一个好的开始。您还找到了它所在的界限:
simulation.controller.setInspectors(inspectors,names); //1737
根据您对NPE的了解,您可以推断simulation
或controller
为null
。
println
语句来确定哪个?
如果没有,并且您正在使用IDE(您可能是),那么从您刚刚打开的源开始,在第1737行之前放置一个断点。当到达该行时,使用调试器检查变量{ {1}}然后simulation
查看哪个是simulation.controller
。具体如何做到这一点取决于你的IDE,但不应该很难找到using XKCD's tech support cheat sheet。
然后你可能会知道原因。如果没有,请继续阅读源代码,例如:看起来达到1737行的水平。