Добавление изображения в JPanel через ImageIO.read?

#java #swing #io #jpanel #paintcomponent

#java #качать #io #jpanel #компонент paint

Вопрос:

Я пытаюсь добавить JPanel с изображением в нем. Я использую ImageIO.read для получения пути, но я получаю исключение IOException, в котором говорится: не удается прочитать входной файл

Изображение называется TCHLogo. Это PNG внутри папки ‘res’ внутри моего проекта.

Если есть какой-либо лучший способ отображения этого изображения, пожалуйста, также упомяните его!

Вот код для моей JPanel:

 import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel{

    private BufferedImage image;

    public ImagePanel() {
        try {                
           //THIS LINE BELLOW WAS ADDED
           image = ImageIO.read(getClass().getResourceAsStream("res/TCHLogo.png"));
        } catch (IOException ex) {
             // handle exception...
            System.out.println(ex);
        }
     }

     @Override
     public void paintComponent(Graphics g) {
         super.paintComponent(g);  //THIS LINE WAS ADDED
         g.drawImage(image, 0, 0, null); // see javadoc for more info on the parameters
     }

}
  

Вот как я добавляю JPanel в свой апплет:

 ImagePanel appletRunningPanel;
appletRunningPanel = new ImagePanel();
appletRunningPanel.setSize(300, 300);
appletRunningPanel.validate();
add(appletRunningPanel);
  

Редактировать
Я создал папку внутри корзины, в которую приложение начинает просматривать в данный момент..
папка называется res, и изображение находится внутри..

Теперь я получаю следующее исключение IOException при запуске строки:

 image = ImageIO.read(getClass().getResourceAsStream("res/TCHLogo.png"));
  

Вот журнал ошибок:

 java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(ImageIO.java:1338)
    at surprice.applet.ImagePanel.<init>(ImagePanel.java:17)
    at surprice.applet.MainClass.init(MainClass.java:41)
    at sun.applet.AppletPanel.run(AppletPanel.java:436)
    at java.lang.Thread.run(Thread.java:679)
  

Ответ №1:

Вероятно, путь к файлу вашего изображения неверен относительно каталога пользователя. Чтобы узнать, где Java начинает искать, где находится каталог пользователя, поместите что-то вроде этой строки кода где-нибудь в вашей программе:

 System.out.println(System.getProperty("user.dir"));
  

Возможно, вам было бы лучше получить изображение как входной поток, полученный из ресурса, а не как файл. например,

 image = ImageIO.read(getClass().getResourceAsStream("res/TCHLogo.png"));
  

Это приведет к поиску изображения по указанному пути относительно расположения файлов класса, и фактически это то, что вы должны сделать, если ваше изображение находится в вашем файле jar.

Правка 2
Кроме того, часто вам нужно сначала вызвать метод paintComponent super, прежде чем выполнять какой-либо собственный рисунок, чтобы можно было выполнить необходимый уход, например, избавиться от «грязных» фрагментов изображения. например, измените это:

  public void paintComponent(Graphics g) {
     g.drawImage(image, 0, 0, null); 
 }
  

к этому:

  public void paintComponent(Graphics g) {
     super.paintComponent(g); // **** added****
     g.drawImage(image, 0, 0, null); 
 }
  

Комментарии:

1. Он начинает искать в workspace / Applet / bin.. Может быть, я смогу создать папку в папке bin проекта.. Но будут ли эти изображения также в файле .jar, когда я его экспортирую?

2. @TheCompBoy: они будут в jar, если вы поместите их в jar. Что вы используете для редактирования своих программ, IDE? Если у вас так много мастеров, которые помогут вам создать файл jar и добавить выбранные файлы и ресурсы.

3. Когда я пытаюсь использовать вашу строку кода (image=ImageIO.read(getClass().getResourceAsStream(«res / TCHLogo.png»));) я получаю это сообщение об ошибке: java.lang. Исключение IllegalArgumentException: ввод == null! в javax.imageio. ImageIO.read(ImageIO.java:1338) в surprice.applet. Панель изображений. <инициализация>(ImagePanel.java:17) в surprice.applet. MainClass.init(MainClass.java:41) в sun.applet. AppletPanel.run(AppletPanel.java:436) на java.lang. Thread.run(поток.java:679)

4. @TheCompBoy: где находится ваш файл изображения относительно файлов вашего класса?

5. @TheCompBoy Я решил аналогичную проблему, используя getClass().getClassLoader().getResourceAsStream(path) вместо

Ответ №2:

Я написал этот класс ImagePanel, который я использую для этой области :

 public class ImagePanel extends JPanel {

    private static final long serialVersionUID = 7952119619331504986L;
    private BufferedImage image;

    public ImagePanel() { }

    public ImagePanel(String resName) throws IOException {
        loadFromResource(resName);
    }

    public ImagePanel(BufferedImage image) {
        this.image = image;
     }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(image, 0, 0, null); // see javadoc for more info on the parameters

    }

    public BufferedImage getImage() {
        return image;
    }

    public void setImage(BufferedImage image) {
        this.image = image;
    }

    /**
     * Load the Image from a File
     * @param path image name and path
     * @throws IOException
     */
    public void loadFromFile(String path) throws IOException {
        image = ImageIO.read(new java.io.File(path));
    }

    /**
     * Load Image from resource item
     * @param resName name of the resource (e.g. : image.png)
     * @throws IOException
     */
    public void loadFromResource(String resName) throws IOException { 
        URL url = this.getClass().getResource(resName);
        BufferedImage img = ImageIO.read(url);

        image = img;
    }
}
  

Затем я использую ImagePanel таким образом :

  //Inizialization of the ImagePanel
 ImagePanel panelImage = new ImagePanel();
//Try loading image into the image panel
        try {
            panelImage.loadFromResource("/Resources/someimage.png");
        } catch (java.io.IOException e) {
                //Handling Exception
        }
  

Комментарии:

1. как есть, ваша реализация paintComponent недопустима: по умолчанию JPanel сообщает, что он непрозрачен — как таковой, он гарантирует заполнение каждого пикселя. Плюс: он должен реализовать getXXSize, чтобы упростить работу LayoutManagers 🙂