BufferedImage没有出现在JFrame

问题描述

这是我的第二个Java项目,对编程我是完全陌生的,但是我已经从事了很长一段时间。但是,代码可能一团糟。我正在尝试在JFrame中重现Image,但是我不知道如何解决所述问题。可能是文件格式错误吗? 当我将package文件夹和图像文件插入为路径时,即使看起来没有任何内容,它也可以编译而不会显示错误消息。将路径更改为桌面(或其他任何内容)后,出现以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at Informatik.Timezones.main(Timezones.java:287)

显然没有找到源,这意味着以前已经正确识别了源。也许我在JFrame而不是Label或Panel上绘图,这会导致问题。

这是main方法中代码的一部分,该方法生成Panel并绘制图像。

    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();
    }
}

这是我的代表:

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,null);
}
      
    public static void main (String args []) {

    JFrame zeichnen = new JFrame(); 
    face = new JLabel();
    face.setVisible(true);
    face.setSize(1000,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,this);
}

public static void main(String args[]) {
Runnable r = () -> {
    new TestImageLoad();
};
SwingUtilities.invokeLater(r);
}
}

解决方法

对新(有效)代码的评论

类加载器是加载应用程序资源的便捷工具,但是有一些技巧可以使它们正常工作:

(但首先是个人而言)出于各种原因,我避免使用getResourceAsStream方法。其中主要的是:

  • getResource返回一个URL。发生错误时,调试起来会更容易,因为我们可以打印出URL并检查它指向我们 think 应该指向的位置。如果没有找到资源,它将是null,但是当我们在类路径中有两个同名资源并且没有获取我们想要的资源时,它也会发出警告。后者很少见,但确实会发生。
  • 如果我们需要URL中的InputStream,则它只是一个方法调用。简单。 OTOH许多方法在URL或(表示String的{​​{1}}等或File(特别适用于Java Sound)中,都可以更好地(甚至仅)工作。 ,可能还有其他事情),并且通常不会缓冲BufferedInputStream方法返回的流。同样,它只是修复该问题的一行代码,但它可能使我们失望。而且,如果该方法采用的是URL,则将全部自动处理。
  • 他们使用不同的规则来查找资源。这似乎是Sun / Oracle的愚蠢决定,但是。我通常建议人们用getResourceAsStream前缀路径,以确保他们直接从类路径的根开始。 /可以正常工作,但是getResource可以..不同。老实说,人们试图解释这些差异的复杂性,但我调低了。 getResourceAsStream有效,这就是我所使用的。

好的,现在我已经解释了为什么我建议使用getResource并重新使用技巧。

  1. 好吧,您已经使用了上面提到的一个。即通过添加getResource作为前缀。
  2. 但最重要的是, root context 类加载器之间的区别。我在尝试使用/方法(为主机main设置图标)中获取资源时遇到了无数的麻烦。事实证明,该调用使用的是系统或根类加载器,该加载器仅用于加载系统(例如JRE API类)资源。为了使搜索更快,它的类路径非常有限。 context 类加载器是可以在其上获取我们的嵌入式资源的类加载器。但是像JFrame这样的调用通常会获取根类加载器,而不是上下文。为了获得上下文类加载器,它始终可以正常工作,代码是从构造函数或自定义类的方法中调用的,并使用实例化的对象(例如TimeZone.class.getClassLoader())。

旧代码

原始代码将标签添加到框架,但未添加绘制图像的自定义涂漆面板!这样做的方法是将自定义绘制面板添加到框架,然后将标签添加到该面板。

原始代码一团糟。我进行了重组,并修复了许多问题。太多的事情我忘记了。相反,请参考此代码以获取详细信息。

首先检查此代码在您的系统/环境上是否可用,然后获取 此代码 您的图片 一起使用>,但这似乎仍然是一个问题。

this

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...