I have a memory match program that allows users to add new folders and and images into them. When the program runs with the default folder and images it works fine. When it selects the user added folder it gets to the point where it adds the first image and then gives a NullPointerException
.
Here is the code where I think the problem is
ArrayList <Card> cardsList = new ArrayList();
//cboDifficulty.addActionListener(this);
String difficulty = cboDifficulty.getSelectedItem().toString();
gameDiff = 0;//initialize gameDiff to 0
if(difficulty.equals("Beginner")){//Beginnner
/*place 3 cards and 1 copy of each card (total of 6 cards) on gamescreen*/
gameDiff = 3;
}
else if(difficulty.equals("Easy")){//Easy
/*place 6 cards and 1 copy of each card (total of 12 cards) on gamescreen*/
gameDiff = 6;
}
String userDir = cboImages.getSelectedItem().toString();
File filePath = new File(baseDir + "/" + userDir + "/");
comboFile = filePath.listFiles();
List<File> listShuffle = Arrays.asList(comboFile);
Collections.shuffle(listShuffle);
for(int tick = 0; tick < listShuffle.size(); tick++){
comboFile[tick] = listShuffle.get(tick);
}
for(int ctr = 0; ctr < comboFile.length; ctr++){
if(ctr < gameDiff){
Card card = new Card();
card.setbackImage(new ImageIcon(cardBackImage));
Image img = null;
if(comboFile[ctr].isFile()){
JOptionPane.showMessageDialog(null, comboFile[ctr].toString());
The next line is where the NullPointerException
is at
img = new ImageIcon(this.getClass().getResource(comboFile[ctr].getPath())).getImage();
}
Image dimg = img.getScaledInstance(144, 216, Image.SCALE_SMOOTH);
card.setfrontImage(new ImageIcon(dimg));
// Populate card with db results
cardsList.add(card);
}
}
// Clone list of cards for game
for(int counter = 0; counter < gameDiff && counter < cardsList.size(); counter++){
// Pull out current card from the loop
Card orgCard = cardsList.get(counter);
// Make new card to populate (clone it)
Card cloneCard = new Card();
cloneCard.setfrontImage(orgCard.getfrontImage());
cloneCard.setbackImage(orgCard.getbackImage());
cardsList.add(cloneCard);
}
shuffleCard(cardsList);
createGameScreen(cardsList);
As stated this code works fine when I use the default folder it only breaks when it attempts to use user supplied images.
Here is the code that creates the directory:
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(null);
fc.setFileSelectionMode(fc.DIRECTORIES_ONLY);
if (returnVal == fc.APPROVE_OPTION) {
File selectedFile = fc.getSelectedFile();
imageFilename = selectedFile.getPath();
JOptionPane.showMessageDialog(null, "You selected " + imageFilename);
ImageIcon imageView = new ImageIcon(imageFilename);
lblIcon.setIcon(imageView);
Here is the code that saves the image
String sveCaption = lblCaption.getText();
// Convert text in combobox to string...
String newDir = cboSelectGroup.getSelectedItem().toString();
// Convert path to string...
String src = baseDir + "/" + newDir;
// Create new file...
File javaFilePath = new File(src, "/" + lblCaption.getText() + ".png");
File oldImage = new File(imageFilename);
if (! javaFilePath.exists()){
JOptionPane.showMessageDialog(null, "Folder/Category, Image and Caption saved!!!");
//oldImage.renameTo(javaFilePath);
FileChannel copyFile = new FileInputStream(oldImage).getChannel();
FileChannel dest = new FileOutputStream(javaFilePath).getChannel();
dest.transferFrom(copyFile, 0, copyFile.size());
}
The save creates a new file in the folder selected by the user. The game even sees the file as it will enter the if statement and print the message I added in. But at that point it gives the exception.
I forgot to say that the message printed just before the exception is showing the expected path images/userfolder/userimage.png.
This code:
this.getClass().getResource(comboFile[ctr].getPath())
... relies on the image being available as a resource in the same classloader as the executing class. If it's just a file on the file system and the class is in a jar file, that won't be the case.
If you're just trying to load a file, don't use Class.getResource()
- just pass the filename (ideally an absolute filename to avoid any ambiguity) to the ImageIcon
constructor.
See more on this question at Stackoverflow