Загрузка изображений из Jarfile

Хорошо, вот моя проблема и мой вопрос к тебе.....

У меня есть игра, в которой ему нужно загружать изображения из файла jar (все изображения упакованы в файл jar так:) Сначала я разархивирую файл jar:

Затем он переходит к:

Тогда внутри каждой из этих папок у меня есть что-то похожее на это:

Теперь напоминание выше, это Jarfile GameClient.jar unziped, и вы видите, где находятся карты.

Итак, вот мой код для загрузки каждого из этих изображений в память

private void addCardsAndChangeSize() throws IOException
{ String tempString; ImageIcon tempIcon; allCards.clear(); ClassLoader cldr = this.getClass().getClassLoader(); URL imageURL; for(int i = 0; i < all.length; i++) { for(int x = 0; x < clubs.length; x++) { tempString = all[i][x]; tempString = "/cards/"+cardFolders[i]+"/"+tempString; imageURL = cldr.getResource(tempString); tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false); tempString = all[i][x]; tempIcon.setDescription(tempString); allCards.add(tempIcon); } } backCard = resizeImage(new ImageIcon(cldr.getResource(back)),70,70,false);
}

Поэтому я называю, что в contructor для загрузки всех изображений в ArrayList вот весь класс, если вы хотите знать, что я делаю.

package global;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Cards
{
private ImageIcon backCard = new ImageIcon("cards/backCard.jpg");
private String back = "/cards/backCard.jpg";
private String[] cardFolders = { "clubs","diamonds","hearts","spades"
};
private String[] clubs = { "aceClubs.jpg","eightClubs.jpg","fiveClubs.jpg","fourClubs.jpg","jackClubs.jpg", "kingClubs.jpg","nineClubs.jpg","queenClubs.jpg","sevenClubs.jpg","sixClubs.jpg", "tenClubs.jpg","threeClubs.jpg","twoClubs.jpg"
};
private String[] diamonds = { "aceDia.jpg","eightDia.jpg","fiveDia.jpg","fourDia.jpg","jackDia.jpg","kingDia.jpg", "nineDia.jpg","queenDia.jpg","sevenDia.jpg","sixDia.jpg","tenDia.jpg","threeDia.jpg", "twoDia.jpg"
};
private String[] hearts = { "aceHearts.jpg","eightHearts.jpg","fiveHearts.jpg","fourHearts.jpg","jackHearts.jpg", "kingHearts.jpg","nineHearts.jpg","queenHearts.jpg","sevenHearts.jpg","sixHearts.jpg", "tenHearts.jpg","threeHearts.jpg","twoHearts.jpg"
};
private String[] spades = { "aceSpades.jpg","eightSpades.jpg","fiveSpades.jpg","fourSpades.jpg","jackSpades.jpg", "kingSpades.jpg","nineSpades.jpg","queenSpades.jpg","sevenSpades.jpg","sixSpades.jpg", "tenSpades.jpg","threeSpades.jpg","twoSpades.jpg"
};
private String[][] all = { clubs,diamonds,hearts,spades
};
private ArrayList<imageicon> allCards = new ArrayList<imageicon>();
public Cards()
{ try { addCardsAndChangeSize(); shuffle(); } catch(Exception e) {e.printStackTrace();}
}
/** * @param x Cards name with extension * @return Face Value of Card */
public static int getFaceValue(String x)
{ int face = 0; switch(x) { case "aceClubs.jpg": case "aceDia.jpg": case "aceHearts.jpg": case "aceSpades.jpg": face = 1; break; case "eightClubs.jpg": case "eightDia.jpg": case "eightHearts.jpg": case "eightSpades.jpg": face = 8; break; case "fiveClubs.jpg": case "fiveDia.jpg": case "fiveHearts.jpg": case "fiveSpades.jpg": face = 5; break; case "fourClubs.jpg": case "fourDia.jpg": case "fourHearts.jpg": case "fourSpades.jpg": face = 4; break; case "jackClubs.jpg": case "jackDia.jpg": case "jackHearts.jpg": case "jackSpades.jpg": case "kingClubs.jpg": case "kingDia.jpg": case "kingHearts.jpg": case "kingSpades.jpg": case "queenClubs.jpg": case "queenDia.jpg": case "queenHearts.jpg": case "queenSpades.jpg": case "tenClubs.jpg": case "tenDia.jpg": case "tenHearts.jpg": case "tenSpades.jpg": face = 10; break; case "twoClubs.jpg": case "twoDia.jpg": case "twoHearts.jpg": case "twoSpades.jpg": face = 2; break; case "threeClubs.jpg": case "threeDia.jpg": case "threeHearts.jpg": case "threeSpades.jpg": face = 3; break; case "sixClubs.jpg": case "sixDia.jpg": case "sixHearts.jpg": case "sixSpades.jpg": face = 6; break; case "sevenClubs.jpg": case "sevenDia.jpg": case "sevenHearts.jpg": case "sevenSpades.jpg": face = 7; break; case "nineClubs.jpg": case "nineDia.jpg": case "nineHearts.jpg": case "nineSpades.jpg": face = 9; break; } return face;
}
//shuffles all the cards in the deck
private void shuffle()
{ long seed = System.nanoTime(); Collections.shuffle(allCards, new Random(seed));
}
/** * Chooses a card at random from the deck. Also removes that card when chosen * @return randomly chosen card */
public ImageIcon getRandomCard()
{ int index = ((int)Math.random() * allCards.size()); return allCards.remove(index);
}
/** * @return Image of the back of a card */
public ImageIcon getBackCard()
{return backCard;}
public static ImageIcon parseImage(String x)
{ if(x.contains("Dia")) return new ImageIcon("cards/diamonds/"+x); else if(x.contains("Clubs")) return new ImageIcon("cards/clubs/"+x); else if(x.contains("Hearts")) return new ImageIcon("cards/hearts/"+x); else if(x.contains("Spades")) return new ImageIcon("cards/spades/"+x); return null;
}
//adds all the cards and adds a description to them loaded into memory
private void addCardsAndChangeSize() throws IOException
{ String tempString; ImageIcon tempIcon; allCards.clear(); ClassLoader cldr = this.getClass().getClassLoader(); URL imageURL; for(int i = 0; i < all.length; i++) { for(int x = 0; x < clubs.length; x++) { tempString = all[i][x]; tempString = "/cards/"+cardFolders[i]+"/"+tempString; imageURL = cldr.getResource(tempString); tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false); tempString = all[i][x]; tempIcon.setDescription(tempString); allCards.add(tempIcon); } } backCard = resizeImage(new ImageIcon(cldr.getResource(back)),70,70,false);
}
//resizes images
public ImageIcon resizeImage(ImageIcon imageIcon, int width, int height, boolean max)
{ Image image = imageIcon.getImage(); Image newimg = image.getScaledInstance(-1, height, java.awt.Image.SCALE_SMOOTH); int width1 = newimg.getWidth(null); if ((max && width1 > width) || (!max && width1 < width)) newimg = image.getScaledInstance(width, -1, java.awt.Image.SCALE_SMOOTH); return new ImageIcon(newimg);
}
</imageicon></imageicon>

}

Я продолжаю получать исключение null-указателя на tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);

Может ли кто-нибудь сказать мне, почему это неправильно загружает изображения? Напоминание я предварительно загружаю их в память. Мой вопрос заключается не в том, как сделать это лучше, я просто спрашиваю, что я делаю неправильно с загрузчиком классов и тому подобное...

Я немного новичок в java, и я знаю, что некоторые из этого кода будут выглядеть ужасно для вас, но, пожалуйста, снова, я не спрашиваю, как сделать этот код "pro" im, просто ищет объяснение, почему оно дает мне null.

Благодарю!

PS Если вам нужно больше фотографий с информацией, или мы постараемся сразу это исправить

3 ответа

Вы должны использовать getResource Class, а не ClassLoader. Метод getResource в Class делает полезные преобразования на пути перед тем, как ClassLoader версии ClassLoader метода, например, решить, относится ли путь к классу или абсолюту, и поэтому ClassLoader не ожидает увидеть такие вещи, как / в начале пути. Это можно увидеть в javadoc getResource.


Ваша проблема в том, что cldr.getResource(tempString); не возвращает объект, но null. Тогда что-то не так с tempString. Classloader не может найти этот файл, поэтому возвращает null.

Измените tempString = "/cards/"+cardFolders[i]+"/"+tempString;

К tempString = "cards/"+cardFolders[i]+"/"+tempString;


Поэтому я узнал о решении, которое до сих пор не совсем понял, почему это ответ, но здесь я пойду.

Это переработанный код и отлично работает

private void addCardsAndChangeSize() throws Exception
{ String tempString; ImageIcon tempIcon; allCards.clear(); URL imageURL; for(int i = 0; i < all.length; i++) { for(int x = 0; x < clubs.length; x++) { tempString = all[i][x]; tempString = "/cards/"+cardFolders[i]+"/"+tempString; imageURL = this.getClass().getResource(tempString); System.out.println(tempString); System.out.println(imageURL == null); tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false); tempString = all[i][x]; tempIcon.setDescription(tempString); allCards.add(tempIcon); } } backCard = resizeImage(new ImageIcon(this.getClass().getResource(back)),70,70,false);
}

У вас должен быть этот "/cards/", а также вы this.getClass(). GetResource (String res);

Спасибо всем за помощь!

licensed under cc by-sa 3.0 with attribution.