Как использовать DrawImage() с рандомизированным списком изображений

Здравствуйте, мне нужна помощь в рисовании изображения с использованием метода drawImage() из этого массива, содержащего изображения. Это должно быть случайным. Сначала это была программа, которая генерировала случайные буквы, но после некоторых предложений я изменил drawString() для букв на drawImage() для моего массива изображений. Более конкретно, эта строка кода прямо здесь g.drawImage(PicList.get($ranNum), $ranNum, y, this); Я не ожидаю, что кто-то сделает мою домашнюю работу для меня. Мне просто нужна помощь, чтобы понять это.NETBeans не показывает никаких ошибок, но когда я запускаю свою программу, и образы должны упасть, я получаю исключение NullPointer. "Исключение в потоке"AWT-EventQueue-0" java.lang.NullPointerException" Любая помощь будет оценена. Я не знаю много Java, и вещи начинают идти у меня над головой. Вот мои полные уроки. РЕДАКТИРОВАТЬ: я понимаю, почему эта ошибка происходит, я знаю, что есть другие вопросы, как это. Но мой код немного сложнее, чем эти примеры, и они мне сейчас не помогают.

/*******************************************************************************    **
* LearningLetterPanel.java
 * Panel class which which uses threads and overwrites the run method
* to display a panel which has letters that go from the top of the panel
 * to the bottom. The colors are set each iteration to a new color.
* It is used by Panel class
 *********************************************************************************/

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;


class LearningLetterPanel extends JPanel implements Runnable {
public static Thread letterThread = null;
private int y = 10;
static long nLetterDropped = 1;
RandNum rn = new RandNum();
int $ranNum = rn.ranNum();
String $letter = rn.ranNumLetter();
Color $letterColor= rn.ranNumColor();
    public java.util.List<Image> PicList; // here I am making a list to     store my images.

    public Image pic = null;

/***************************************************************************************
*  main method in the class for starting and stopping the thread
************************************************************************************/
LearningLetterPanel()  {
    if (letterThread == null) {
    letterThread = new Thread(this);
    letterThread.start();
        }
}

/***************************************************************************************
    *  Creates the thread and uses Thread.sleep to set the speed of the     movement
    ********************************************************************************    ****/

public void run() {
    Thread myThread = Thread.currentThread();
    while (letterThread == myThread) {
      try{
          Thread.sleep(20);
       }
       catch (InterruptedException e){}
       repaint();
        }
     }

/***************************************************************************************
* the paint method draws the letter based on color(ranNumLetter), location($ranNum and y)
* and speed (y += 3 with Thread.sleep from run())
*************************************************************************************/

    @Override
 public void paint(Graphics g) {

    g.setFont(new Font("Courier", Font.BOLD+Font.ITALIC, 48));
    g.setColor(Color.white);
    //g.drawString($letter, $ranNum, y);
    g.drawImage(PicList.get($ranNum), $ranNum, y, this);
    y += 3;
    Dimension d = getSize();
    if (y > (d.width - 10))
       {y = 10;
       LearningLetterPanel.nLetterDropped +=1;
       $ranNum = rn.ranNum();
       this.$letter = rn.ranNumLetter();
       this.$letterColor = rn.ranNumColor();
       }

    g.setFont(new Font("Courier", Font.BOLD+Font.ITALIC, 48));
    g.setColor($letterColor);
    //g.drawString($letter, $ranNum, y);

    g.drawImage(PicList.get($ranNum), $ranNum, y, this);
 }
        public void RandomImagePane() throws IOException {
        PicList = new ArrayList<Image>(25);

        // here I am adding the images to the list
        PicList.add(ImageIO.read(getClass().getResource("/images/aa.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/bb.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/cc.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/dd.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/ee.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/ff.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/gg.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/hh.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/ii.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/jj.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/kk.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/ll.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/mm.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/nn.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/oo.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/pp.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/qq.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/rr.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/ss.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/tt.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/uu.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/vv.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/ww.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/xx.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/yy.png")));
        PicList.add(ImageIO.read(getClass().getResource("/images/zz.png")));  



    }

/***************************************************************************************
*  sets thread to null which stops the thread
************************************************************************************/
 public static void stop() {
    letterThread = null;
    }

/***************************************************************************************
*  Returns the random letter when called
************************************************************************************/
public String getLetter() {
    return this.$letter;
}
  }

Вот класс, откуда эти методы:

    import java.util.*;
    import java.awt.*;
    import java.util.List;
    import java.io.*;
    import javax.imageio.ImageIO;
    import javax.swing.JPanel;

   /***************************************************************************************
       * This class is to be used for random numbers, letters, or colors
        * Using the Math.random class
   ************************************************************************************/

       public class RandNum {
        private String $alphabet="ABCDEFGHIJKLMNOPQRSTUVWXZY";
       private int $width=640;

       /*******************************************************************************       ********
      *     This class is to be used for random numbers
      * Using the Math.random class
     ************************************************************************************/
    public int ranNum() {
    int $ranNumber = 20 + (int)(Math.random() * $width);
    return $ranNumber;
}
/***             
        * This method is to be used for random letters
          * Using the Math.random class
        */
     public String ranNumLetter() {
    int $ranNumLetter = 0 + (int)(Math.random() * 26);
    String $letter = $alphabet.substring($ranNumLetter, $ranNumLetter+1);
    return $letter;
}
    /****
       * This method is to be used for colors
       * Using the Math.random class for each of the three RGB
      ************************************************************************************/

    public Color ranNumColor() {
    int $ranColorRed = 0 + (int)(Math.random() * 256);
    int $ranColorBlue = 0 + (int)(Math.random() * 256);
    int $ranColorGreen = 0 + (int)(Math.random() * 256);
    Color  c = new Color($ranColorRed, $ranColorBlue, $ranColorGreen);
   return c;
}
}

1 ответ

Решение

Как кажется, вы не инициализируете свой список. Прежде чем вы сможете обратиться к своему списку PicList (который должен называться picList, кстати, поскольку это имя поля, а не имя класса), вам необходимо его инициализировать.

Вы уже написали это в RandomImagePane(), но, похоже, не вызываете его (аналогично, он должен называться initRandomImageList со строчными буквами и именем, описывающим его назначение).

(Придерживаясь вашего имени сейчас) Измените конструктор LearningLetterPanel:

LearningLetterPanel()  {
    try {
        RandomImagePane();
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
    letterThread = new Thread(this);
    letterThread.start();
}

Альтернативой перехвату IOException будет заставить конструктор генерировать IOException, но вам все равно нужно где-то его перехватить. Я взял на себя смелость удалить тест для letterThread == null, так как это всегда имеет место в конструкторе (если вы создаете только один экземпляр)

Другие вопросы по тегам