【问题标题】:Null pointer exception when access index of a DefaultListModel访问 DefaultListModel 的索引时出现空指针异常
【发布时间】:2012-07-23 14:59:28
【问题描述】:

我有一个清单:

JList characterList = new JList(characterListModel);
characterListModel = new DefaultListModel();        
String myCharacters[]={"Dean Winchester","Sam Winchester",
            "Bobby Singer","Castiel"};
for (String myCharacter : myCharacters) {
        ((DefaultListModel) characterList.getModel()).addElement(myCharacter);  
}

我已经编写了一个方法,在一个单独的类中,用于删除选定索引处的字符:

public void removeCharacter() {
    DefaultListModel characterListModel = ((PlayerContentPane) IViewManager.Util.getInstance()
        .getMyContainerPane().getMyPlayerManagerPane().getContentPane())
        .getCharacterListModel();
    JList characterList = ((PlayerContentPane) IViewManager.Util.getInstance()
        .getMyContainerPane().getMyPlayerManagerPane().getContentPane())
        .getCharacterList();
    int idx = characterList.getSelectedIndex(); //<---line 62
    int size = characterListModel.getSize();
    characterListModel.remove(idx);
    if (size == 0) { 
        //do nothing
    } else { 
        if (idx == characterListModel.getSize()) {
            idx--;
        }

        characterList.setSelectedIndex(idx);
        characterList.ensureIndexIsVisible(idx);
    }

}

然而,当我用我的按钮运行它时,我得到了这个堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.detica.LarpDB.Controller.Controller.removeCharacter(Controller.java:62)
at com.detica.LarpDB.view.PlayerContentPane$3.actionPerformed(PlayerContentPane.java:94)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

我在谷歌上看到的很多问题都来自以下行:DefaultListModel characterListModel = .... 他们遇到的问题是他们创建了对象的new 实例,现在我对整个Java 事物只是新手,但这对我来说不应该是问题,因为我没有做任何新的,我刚刚具体说明了这是哪个对象。

请问有人可以帮我解开吗?

【问题讨论】:

  • 您至少应该对您的 PlayerContentPane 对象进行变量引用,这样您就不必一直这样做((PlayerContentPane) IViewManager.Util.getInstance().getMyContainerPane().getMyPlayerManagerPane().getContentPane())....
  • 是的,这要容易得多,我认为制作您需要访问类变量的任何组件,例如在本例中将 characterList 设为类变量,因此您只需拥有它而无需继续寻找。
  • 只是为了省点麻烦:与其创建默认模型的实例,然后将数组的所有元素添加到该模型,不如直接使用带有数组的构造函数创建列表?
  • @Jay,removeCharacter 方法在别处,所以我需要某种从该类外部访问它的方法。在我整理我的程序时,这只是一个占位符。
  • 所以让 characterList 成为一个类变量,并将其公开,或者如果您是反对公共变量的学校,请为它提供一个公共访问器。

标签: java nullpointerexception defaultlistmodel


【解决方案1】:

这两行会产生很多问题:

DefaultListModel characterListModel = ((PlayerContentPane) IViewManager.Util.getInstance()
    .getMyContainerPane().getMyPlayerManagerPane().getContentPane())
    .getCharacterListModel();
JList characterList = ((PlayerContentPane) IViewManager.Util.getInstance()
    .getMyContainerPane().getMyPlayerManagerPane().getContentPane())
    .getCharacterList();

如果任何链接方法返回 null(无论出于何种原因),该行将抛出 NullPointerException。

我建议您将它们分成几行并检查每个调用的值,看看您从哪里获得null

编辑

刚刚意识到第 62 行是int idx = characterList.getSelectedIndex();。这意味着characterList 为空。

【讨论】:

  • @Pureferret 查看我的编辑 - 如果您在该行获得 NPE,则意味着 characterList 为空。
  • 我将它固定在列表中,然后从JList characterList = new JList(characterListModel); 中删除了JList。知道为什么会这样吗?
  • 我没有看到你的代码,所以我只能猜测。 Jlist characterList = new ... 创建一个名为 characterList 的新局部变量。如果您的类还有一个名为characterList 的成员,则此局部变量将隐藏将保留其默认值(在本例中为:null)的类成员,并且getCharacterList() 返回该值。通过删除语句中的JList,您将新列表分配给类成员而不是局部变量,您的代码现在可以按预期工作。
  • 这正是我认为正在发生的事情。
【解决方案2】:

如果它在您指示的行失败是第 62 行,那么该行上引用的唯一对象,因此唯一可能为 null 的对象是 characterList。这意味着您的 getCharacterList 函数返回 null。 (如果错误在 getSelectedIndex 函数内部,那么您的堆栈跟踪中将有另一行。)

由于您没有发布 getCharacterList 函数,我不能多说。但是你应该看看那个函数,看看在什么情况下它会返回 null。

【讨论】:

  • 如果列表为空,它只能返回空。
  • 代码类似于return CharacterList,我不确定它怎么会有错误。
  • 那么变量 CharacterList 没有被正确设置。正如我所说,没有看到更多相关代码,我只能在黑暗中拍摄。
  • 考虑到我已经解决了这个问题,不幸的是,我认为这不值得进一步讨论。
猜你喜欢
  • 2015-03-22
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2018-06-06
相关资源
最近更新 更多