2

Hi, this is my first time posting to stackoverflow and I'm kinda new with java so bear with me and I'm sorry if I'm posting a repeating or a vague question.

So, I'm trying to make a card based drinking game with custom made cards to try out with some friends. Right now the GUI shows just fine, but after I shuffle the deck and try to draw a card (change the label next to the remaining deck to a icon of the card from my map of cards and card icons.), I get NullPointerException. Can someone help/explain me what i'm doing wrong there?

Here's the stack trace:

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)

Here's part of the code where the error occurs:

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;
    }
}

I'm not sure if I made the cardIconMap correctly so I will post the createCardFaces class too.

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;
        }
    }
}
j08691
  • 204,283
  • 31
  • 260
  • 272
  • Either `labelDealtCard` or `cardIconMap` is `null`. Put a print check to see if any of them is null, and try to find out why. – gparyani Dec 11 '17 at 11:24

2 Answers2

1

Your createCardIconMap() should return an empty map instead of null value.

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

or rewrite your code like below:

(...)
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;

More over, ensure labelDealtCard isn't null.

Stephan
  • 41,764
  • 65
  • 238
  • 329
  • Oh yeah you're right, thanks. Now I don't get any errors but for some reason the labelDealtCard changes to no-icon instead of the image... – Happysausage Dec 11 '17 at 11:31
0

Ultimately, your problem is that "/res" is not a directory that Java is able to find.


Stephan has identified the cause of the exception, but I don't think that's the proper way to handle this.

listFiles will only return null "this abstract pathname does not denote a directory", so perhaps the best way to handle this situation is to throw an exception.

There already one in java.nio.file which fits this situation nicely, NotDirectoryException:

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

Your method already declares IOException as thrown and NotDirectoryException is a subclass so you don't need to change your method signature.

Michael
  • 41,989
  • 11
  • 82
  • 128
  • this resulted in this kind of stack trace: java.nio.file.NotDirectoryException: /res at CreateCardFaces.createCardIconMap(JuomaPeli.java:105) at JuomaPeli.createAndShowGui(JuomaPeli.java:51) at JuomaPeli.access$000(JuomaPeli.java:34) at JuomaPeli$1.run(JuomaPeli.java:75) – Happysausage Dec 11 '17 at 11:50
  • @Happysausage Yes. It will do. It's not a directory. That's ultimately what the problem is. – Michael Dec 11 '17 at 11:50