在游戏中创建自定义卡面时出现NullPointerException?

时间:2017-12-11 11:22:06

标签: java jar nullpointerexception playing-cards

嗨,这是我第一次发布到stackoverflow,我对java有点新意,所以请耐心等待,如果我发布重复或模糊的问题,我很抱歉。

所以,我试图用定制卡制作一个基于卡的饮酒游戏,试着和一些朋友一起试试。现在GUI显示得很好,但是在我洗牌并尝试绘制卡片(将剩余卡片旁边的标签从我的卡片和卡片图标更改为卡片的图标。)时,我得到NullPointerException。有人可以帮助/解释我在那里做错了吗?

这是堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at TablePanel$LabelListener.mousePressed(JuomaPeli.java:219)
    at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
    at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.desktop/java.awt.Component.processEvent(Unknown Source)
    at java.desktop/java.awt.Container.processEvent(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.EventQueue.access$500(Unknown Source)
    at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

这是发生错误的代码的一部分:

public void mousePressed(MouseEvent e) {

    JLabel label = (JLabel) e.getSource();

    if (label == labelRemainingDeck){
        Icon icon = label.getIcon();

        if (icon == null) {
            return;
        } else if (icon == cardBackIcon) {
            Card card = remainingDeck[0];
            if (card == null){
                return;
            } else{
                labelDealtCard.setIcon(cardIconMap.get(card)); //this is the line 219 
                removeCard(); //method that returns remainingDeck without the first card
            }   
        } else{
            label.setIcon(rulesIcon2);
        }
    } else if (label == labelDealtCard){
        Icon icon = label.getIcon();
        if (icon == null){
            return;
        } else if (icon == rulesIcon){
            labelDealtCard.setIcon(rulesIcon2);
        } else if (icon == rulesIcon2){
            labelDealtCard.setIcon(rulesIcon);
        } else
            return;
    } else{
        return;
    }
}

我不确定我是否正确制作了cardIconMap,所以我也会发布createCardFaces类。

class CreateCardFaces {

    public static Map<Card, Icon> createCardIconMap() throws IOException {

        Map<Card, Icon> cardIconMap = new HashMap<Card, Icon>();
        File dir = new File("/res"); //res folder contains all the card images of .png format
        File[] dirListing = dir.listFiles();

        if (dirListing != null){
            for (File f : dirListing)
            {
                for (int rankInt = 0; rankInt < 187; rankInt++) //there's 187 custom cards
                { 
                    BufferedImage cardImage = ImageIO.read(f);
                    Rank rank = Rank.values()[rankInt];

                    cardIconMap.put(new Card(rank), new ImageIcon(cardImage));
            }
            }
            return cardIconMap;
        } else {
            return null;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您的createCardIconMap()应该返回空地图而不是空值。

if (dirListing != null){
     // ...  
     return cardIconMap;
} else {
     return Collections.emptyMap();
}

或重写您的代码,如下所示:

(...)
Map<Card, Icon> cardIconMap = new HashMap<Card, Icon>();
File dir = new File("/res"); //res folder contains all the card images of .png format
File[] dirListing = dir.listFiles();

if (dirListing != null){
        for (File f : dirListing)
        {
            for (int rankInt = 0; rankInt < 187; rankInt++) //there's 187 custom cards
            { 
                BufferedImage cardImage = ImageIO.read(f);
                Rank rank = Rank.values()[rankInt];

                cardIconMap.put(new Card(rank), new ImageIcon(cardImage));
            }
        }
}

return cardIconMap;

此外,确保labelDealtCard不为空。

答案 1 :(得分:0)

最终,您的问题是“/ res”不是Java能够找到的目录。

Stephan has identified the cause of the exception,但我认为这不是解决这个问题的正确方法。

listFiles will only return null "this abstract pathname does not denote a directory",所以处理这种情况的最好方法就是抛出异常。

java.nio.file中已有一个很适合这种情况,NotDirectoryException

if (dirListing != null)
{
    // ... 
}
else
{
    throw new NotDirectoryException("/res");
}

您的方法已将IOException声明为抛出,NotDirectoryException是子类,因此您无需更改方法签名。