BuffereImage不出现在jframe中

kpbpu008  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(393)

这是我的第二个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);
}
}
h7appiyu

h7appiyu1#

对新(现行)规范的评论
类加载器是加载应用程序资源的便利工具,但要让它们正常工作,有几个技巧:
(但首先是个人问题)我避免 getResourceAsStream 方法有多种原因。其中主要有: getResource 返回一个 URL . 出错时更容易调试,因为我们可以打印出url,并在我们认为应该的位置检查它。如果找不到资源,它将被删除 null ,但当类路径中有两个名称相同的资源而它没有获取所需的资源时,它也会发出警告。后者相当罕见,但确实发生过。
如果我们需要 InputStream 从url来看,它只是一个方法调用。容易的。有很多方法可以更好地(甚至只)在 URL 或(a) String 代表)a File 等等,或者 BufferedInputStream (这特别适用于java声音,可能还有其他东西)和从 getResourceAsStream 方法通常不缓冲。再说一次,这只是一行代码来解决这个问题,但它可能会绊倒我们。如果该方法采用一个url,则所有这些都将自动处理。
他们使用不同的规则来寻找资源。这似乎是sun/甲骨文的愚蠢决定,但是。。无论什么。我通常建议人们在路径前面加上 / 以确保它们直接从类路径的根开始。这对我来说很好 getResource ,但是。。与…不同 getResourceAsStream . 老实说,人们试图解释这些差异的复杂性,但我置之不理。 getResource 我用的就是这个。
好的,现在我已经解释了为什么我建议使用 getResource ,回到戏法。
你已经用过了,上面提到过。即通过添加 / 作为前缀。
但最重要的是,根类加载器和上下文类加载器之间的区别。我有无数的麻烦,试图获取一个资源的范围内 main 方法(为主机设置图标) JFrame ). 结果发现,调用使用的是系统或根类加载器,它只用于加载系统(例如jreapi类)资源。为了加快搜索速度,它的类路径非常有限。上下文类加载器是可以获取嵌入资源的加载器。但是像这样的电话 TimeZone.class.getClassLoader() 通常将获取根类装入器,而不是上下文。为了获得上下文类加载器,它总是工作的代码是从我们的自定义类的构造函数或方法调用,并使用一个示例化的对象(如 this ).
旧代码
原始代码将标签添加到框架中,而不是绘制图像的自定义绘制面板!方法是将自定义绘制的面板添加到框架中,然后将标签添加到该面板中。
原来的代码乱七八糟。我重新组织了它,并在这样做的同时修复了许多东西。我忘记了很多事情。有关详细信息,请参阅此代码。
首先检查此代码在您的系统/环境中是否正常工作,然后让此代码与您的映像一起工作,这似乎仍然是一个问题。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
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 {
            URL url = new URL("https://i.stack.imgur.com/OVOg3.jpg");
            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);
    }
}

相关问题