Загрузка изображений из 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.