NullPointerException при создании пользовательских карточных лиц в игре?
Привет, я впервые пишу в stackru, и я вроде как новичок в java, так что терпите меня, и мне жаль, если я публикую повторяющийся или расплывчатый вопрос.
Итак, я пытаюсь сделать карточную питьевую игру с заказными картами, чтобы попробовать их с друзьями. Прямо сейчас графический интерфейс показывает очень хорошо, но после того, как я перетасовал колоду и попытался вытянуть карту (смените ярлык рядом с оставшейся колодой на значок карты из моей карты карт и значков карт), я получаю исключение 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 ответа
Ваш 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 не является нулевым.
В конечном счете, ваша проблема в том, что "/res" не является каталогом, который Java может найти.
Стефан определил причину исключения, но я не думаю, что это правильный способ справиться с этим.
listFiles
будет возвращать только ноль "это абстрактное имя пути не обозначает каталог", поэтому, возможно, лучший способ справиться с этой ситуацией - создать исключение.
Там уже один в java.nio.file
что хорошо вписывается в эту ситуацию, NotDirectoryException
:
if (dirListing != null)
{
// ...
}
else
{
throw new NotDirectoryException("/res");
}
Ваш метод уже объявляет IOException
как брошено и NotDirectoryException
это подкласс, поэтому вам не нужно менять сигнатуру вашего метода.