-4

我正在使用GridWorld案例研究。我似乎在提供的程序中发现了一个错误。尝试通过 GUI 创建大小无效的网格并关闭错误消息后,每当我尝试对现有网格执行任何操作时,都会收到 NullPointerException:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at info.gridworld.gui.GUIController$3.mousePressed(GUIController.java:119)
        at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:279)
        at java.awt.Component.processMouseEvent(Component.java:6501)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
        at java.awt.Component.processEvent(Component.java:6269)
        at java.awt.Container.processEvent(Container.java:2229)
        at java.awt.Component.dispatchEventImpl(Component.java:4860)
        at java.awt.Container.dispatchEventImpl(Container.java:2287)
        at java.awt.Component.dispatchEvent(Component.java:4686)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4489)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
        at java.awt.Container.dispatchEventImpl(Container.java:2273)
        at java.awt.Window.dispatchEventImpl(Window.java:2713)
        at java.awt.Component.dispatchEvent(Component.java:4686)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
        at java.awt.EventQueue.access$000(EventQueue.java:101)
        at java.awt.EventQueue$3.run(EventQueue.java:666)
        at java.awt.EventQueue$3.run(EventQueue.java:664)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.awt.EventQueue$4.run(EventQueue.java:680)
        at java.awt.EventQueue$4.run(EventQueue.java:678)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre ad.java:211)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread. java:128)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre   ad.java:117)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

此外,我无法通过提供的 GUI 将网格更改为其他内容:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at info.gridworld.gui.WorldFrame.setGrid(WorldFrame.java:237)
        at info.gridworld.gui.MenuMaker$GridConstructorItem.actionPerformed(MenuMaker.java:344)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
        at java.awt.Component.processMouseEvent(Component.java:6504)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
        at java.awt.Component.processEvent(Component.java:6269)
        at java.awt.Container.processEvent(Container.java:2229)
        at java.awt.Component.dispatchEventImpl(Component.java:4860)
        at java.awt.Container.dispatchEventImpl(Container.java:2287)
        at java.awt.Component.dispatchEvent(Component.java:4686)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
        at java.awt.Container.dispatchEventImpl(Container.java:2273)
        at java.awt.Window.dispatchEventImpl(Window.java:2713)
        at java.awt.Component.dispatchEvent(Component.java:4686)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
        at java.awt.EventQueue.access$000(EventQueue.java:101)
        at java.awt.EventQueue$3.run(EventQueue.java:666)
        at java.awt.EventQueue$3.run(EventQueue.java:664)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.awt.EventQueue$4.run(EventQueue.java:680)
        at java.awt.EventQueue$4.run(EventQueue.java:678)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

我认为这是 GridWorld 程序本身的错误,而不是我编写的任何代码中的错误,因为即使我只是启动程序而没有给它任何执行代码,这似乎也会发生。我进行了一些调查,发现由于某种原因,null每当我尝试在 GUI 中更改网格时,网格都会设置为,并且我尝试创建的网格无效(或者在创建网格时发生任何异常)。为什么网格设置为null?有没有办法我自己在提供的源代码中解决这个问题?

我正在使用的版本是 GridWorld 1.02,可在 GridWorld.info 的“非官方代码”链接下找到。CollegeBoard 网站上的代码较旧。我已经对此进行了测试,并且旧版本也会发生这种情况。

4

2 回答 2

1

我看起来你需要newGrid在调用setGrid(Grid<T> newGrid)a时检查是否为空WorldFrame。我可以通过创建具有负行或列值的网格来重新创建您描述的问题。允许网格设置为 null 似乎会导致 NPE 下行。

对源进行以下更改将修复它。关闭错误消息后,我能够创建一个有效大小的新网格以及使用其他 GUI 功能。

WorldFrame.java:

public void setGrid(Grid<T> newGrid)
{
    if (newGrid == null) {  // this is what I added...
        return;
    }

    Grid<T> oldGrid = world.getGrid();
    Map<Location, T> occupants = new HashMap<Location, T>();
    for (Location loc : oldGrid.getOccupiedLocations())
        occupants.put(loc, world.remove(loc));

    world.setGrid(newGrid);
    for (Location loc : occupants.keySet())
    {
        if (newGrid.isValid(loc))
            world.add(loc, occupants.get(loc));
    }

    display.setGrid(newGrid);
    repaint();
}
于 2013-04-16T20:14:25.550 回答
0

这是发生的事情

NullPointer 异常发生在源文件GUIController.java中,如堆栈跟踪所示。

Grid<T> gr = parentFrame.getWorld().getGrid();
Location loc = display.locationForPoint(evt.getPoint());
if (loc != null && gr.isValid(loc) && !isRunning())

gr,从中检索的getWorld().getGrid()可以为空,并且 if 语句在调用 之前不检查 gr gr.isValid()

溯源:

Grid 由WorldFrame.javasetGrid()中的方法设置,该方法不检查其输入,也就是说,如果您调用该方法,它会将新网格设置为 null。null

setGrid()方法是从 MenuMaker.java 调用的第 343 行)

Grid<T> newGrid = (Grid<T>) invokeConstructor(); 
parent.setGrid(newGrid);

并且该invokeConstructor()方法在异常时返回 null。 这就是你的 null 来自哪里

使固定

确保 WorldFrame.java 中的setGrid不接受空值作为参数。

public void setGrid(Grid<T> newGrid) {
    if (newGrid == null) {
        return;
    }
    // rest of method goes here

一个可能更好但更复杂的解决方案是确保invokeConstructor()inMenuMaker.java不返回 null。通知 GUI 并处理异常(而不是返回 null)将是一个更优雅的解决方案。

希望这可以帮助。

于 2013-04-16T21:09:03.710 回答