这是我的第二个java项目,我对编程完全陌生,但我已经为此工作了很长一段时间了。然而,代码可能是一团糟。我试图在jframe中复制一个图像,但我不知道如何解决所述问题。可能是文件格式的问题吗?当我插入包文件夹和图像文件作为路径时,它编译时没有错误消息,即使它看起来没有绘制任何东西。在我更改了桌面(或其他任何东西)的路径后,出现以下异常:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at Informatik.Timezones.main(Timezones.java:287)
显然没有找到来源,这意味着它以前被正确识别过。也许我是在jframe上画图,而不是在标签或面板上,这就导致了问题。
下面是main方法中生成面板和绘制图像的部分代码。
JFrame zeichnen = new JFrame();
face = new JLabel();
face.setVisible(true);
face.setSize(1000, 1000);
face.setLayout(null);
face.setLocation(0, 0);
zeichnen.add(face);
zeichnen.setVisible(true);
zeichnen.setSize(1000, 1000);
zeichnen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
zeichnen.setLocationRelativeTo(null);
zeichnen.setResizable(false);
zeichnen.setLayout(null);
try {
bildchen = ImageIO.read(Timezones.class.getClassLoader().getResourceAsStream("Info rmatik/a.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这是我的reprex:
package Informatik;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.RenderingHints;
import javax.swing.*;
public class Test extends JPanel{
static JLabel face;
static BufferedImage bildchen;
@Override
public void paintComponent(Graphics maler) {
super.paintComponent(maler);
Graphics2D maler2 = (Graphics2D) maler;
maler2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
maler.drawImage(bildchen, 1000, 1000, null);
}
public static void main (String args []) {
JFrame zeichnen = new JFrame();
face = new JLabel();
face.setVisible(true);
face.setSize(1000, 1000);
face.setLayout(null);
face.setLocation(0, 0);
zeichnen.add(face);
zeichnen.setVisible(true);
zeichnen.setSize(1000, 1000);
try {
bildchen = ImageIO.read(Timezones.class.getClassLoader().getResourceAsStream("/Informatik/a.jpg"));
} catch (IOException e) {
//catch block
e.printStackTrace();
}
zeichnen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
zeichnen.setLocationRelativeTo(null);
zeichnen.setResizable(false);
zeichnen.setLayout(null);
}
}
以下是新的工作版本:
package Informatik;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.print.DocFlavor.URL;
import javax.swing.*;
public class TestImageLoad extends JPanel {
JLabel face;
BufferedImage bildchen;
TestImageLoad() {
initUI();
}
private void initUI() {
JFrame zeichnen = new JFrame();
face = new JLabel("face");
face.setForeground(Color.RED);
zeichnen.add(this);
this.add(face);
try {
java.net.URL url = this.getClass().getResource("/Informatik/a.jpg");
System.out.println(url);
bildchen = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
zeichnen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
zeichnen.pack();
zeichnen.setLocationRelativeTo(null);
zeichnen.setVisible(true);
}
@Override
public void paintComponent(Graphics maler) {
super.paintComponent(maler);
maler.drawImage(bildchen, 0, 0, this);
}
public static void main(String args[]) {
Runnable r = () -> {
new TestImageLoad();
};
SwingUtilities.invokeLater(r);
}
}
1条答案
按热度按时间h7appiyu1#
对新(现行)规范的评论
类加载器是加载应用程序资源的便利工具,但要让它们正常工作,有几个技巧:
(但首先是个人问题)我避免
getResourceAsStream
方法有多种原因。其中主要有:getResource
返回一个URL
. 出错时更容易调试,因为我们可以打印出url,并在我们认为应该的位置检查它。如果找不到资源,它将被删除null
,但当类路径中有两个名称相同的资源而它没有获取所需的资源时,它也会发出警告。后者相当罕见,但确实发生过。如果我们需要
InputStream
从url来看,它只是一个方法调用。容易的。有很多方法可以更好地(甚至只)在URL
或(a)String
代表)aFile
等等,或者BufferedInputStream
(这特别适用于java声音,可能还有其他东西)和从getResourceAsStream
方法通常不缓冲。再说一次,这只是一行代码来解决这个问题,但它可能会绊倒我们。如果该方法采用一个url,则所有这些都将自动处理。他们使用不同的规则来寻找资源。这似乎是sun/甲骨文的愚蠢决定,但是。。无论什么。我通常建议人们在路径前面加上
/
以确保它们直接从类路径的根开始。这对我来说很好getResource
,但是。。与…不同getResourceAsStream
. 老实说,人们试图解释这些差异的复杂性,但我置之不理。getResource
我用的就是这个。好的,现在我已经解释了为什么我建议使用
getResource
,回到戏法。你已经用过了,上面提到过。即通过添加
/
作为前缀。但最重要的是,根类加载器和上下文类加载器之间的区别。我有无数的麻烦,试图获取一个资源的范围内
main
方法(为主机设置图标)JFrame
). 结果发现,调用使用的是系统或根类加载器,它只用于加载系统(例如jreapi类)资源。为了加快搜索速度,它的类路径非常有限。上下文类加载器是可以获取嵌入资源的加载器。但是像这样的电话TimeZone.class.getClassLoader()
通常将获取根类装入器,而不是上下文。为了获得上下文类加载器,它总是工作的代码是从我们的自定义类的构造函数或方法调用,并使用一个示例化的对象(如this
).旧代码
原始代码将标签添加到框架中,而不是绘制图像的自定义绘制面板!方法是将自定义绘制的面板添加到框架中,然后将标签添加到该面板中。
原来的代码乱七八糟。我重新组织了它,并在这样做的同时修复了许多东西。我忘记了很多事情。有关详细信息,请参阅此代码。
首先检查此代码在您的系统/环境中是否正常工作,然后让此代码与您的映像一起工作,这似乎仍然是一个问题。