从Jar文件加载图像

时间:2013-11-18 23:42:58

标签: java image class jar classloader

好的,所以这是我的问题和我的问题.....

我有一个游戏需要从jar文件中加载图像(所有图像都被打包到jar文件中): 我首先解压jar文件: Unziped Jar File

然后它去: cards folder

然后在每个文件夹中我有一些看起来像这样的东西: what the other folders look like also

现在上面的提醒是Jarfile GameClient.jar解压缩,你会看到卡片在哪里。

所以这是我的代码,试图将每个图像加载到内存中

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

所以我在构造函数中调用将所有图像加载到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);
}

}

我一直在tempIcon = resizeImage(new ImageIcon(imageURL),70,70,false);

上获得空指针异常

有谁可以告诉我为什么这不正确加载图像?提醒我将它们预加载到内存中。我的问题不是如何使这更好我只是简单地问我在使用类加载器和类似的东西做错了什么......

我在java方面有点新,我知道这些代码对你来说看起来很可怕但是我再也不会问如何让这段代码“专业”我只是在寻找解释为什么它给我null。

谢谢!

P.S。如果您需要更多信息或w.e.我会尽力把它拿出来

3 个答案:

答案 0 :(得分:3)

你的问题是cldr.getResource(tempString);不返回对象但是null。然后,tempString出了问题。 Classloader无法找到此文件,因此返回null。

更改tempString = "/cards/"+cardFolders[i]+"/"+tempString;

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

答案 1 :(得分:2)

您应该使用getResource的{​​{1}},而不是ClassClassLoader中的getResource方法在将其提供给方法的Class版本之前对路径进行了有用的转换,例如判断路径是相对于类还是绝对,因此{ {1}}不期望在路径的开头看到ClassLoader之类的内容。您可以在getResource javadoc中清楚地看到这一点。

答案 2 :(得分:0)

所以我找到了解决方案,我仍然不太明白为什么这就是答案,但是现在就去。

这是修改后的代码,工作正常

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 /”,还有你.getClass()。getResource(String res);

感谢你们的帮助!