基于代理的模型中的Java NullPointerException

时间:2015-03-31 23:18:51

标签: java

我正在使用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));
                }
            }

外环看起来很好,但我遇到内部问题。建议?

1 个答案:

答案 0 :(得分:1)

我实际上会写你如何通过你给出的图书馆代码来推理,因为你听起来很有能力。

您找到了代码。这是一个好的开始。您还找到了它所在的界限:

 simulation.controller.setInspectors(inspectors,names); //1737

根据您对NPE的了解,您可以推断simulationcontrollernull

你知道哪个?您可以推断一下您可能未能设置或错误传递的代码吗?您可以在代码中放置调试器断点或简单println语句来确定哪个?

如果没有,并且您正在使用IDE(您可能是),那么从您刚刚打开的源开始,在第1737行之前放置一个断点。当到达该行时,使用调试器检查变量{ {1}}然后simulation查看哪个是simulation.controller。具体如何做到这一点取决于你的IDE,但不应该很难找到using XKCD's tech support cheat sheet

然后你可能会知道原因。如果没有,请继续阅读源代码,例如:看起来达到1737行的水平。