#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 🙂