缓冲图像正在读取但未显示

时间:2017-01-22 17:03:56

标签: java swing graphics2d

我是java中的图形新手并且一直试图让它固定下来,但过去两周我一直坚持这个问题。

有两个类,一个读取文件(我认为它正常工作),另一个显示它们。 (我认为问题出在哪里)

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

public class jpaneTesting extends JFrame implements Runnable
{

    public jpaneTesting(int x, int y)
    {
        super("testing");
        this.setBounds( 0, 0, x, y );
        this.setVisible( true );
    }

    @Override
    public void paint( Graphics g )
    {
        Graphics2D g2 = (Graphics2D) g;
        loader loader = new loader();
        BufferedImage character = loader.load("src\\resources\\hey.png"); //accesses hey.png
        g2.drawImage(character,null,5,5);
    }

    @Override
    public void run()
    {
        repaint();
    }

    public static void main (String args[])
    {
        Thread thread = new Thread (new jpaneTesting(500,500));
        thread.start(); //runs the thread that was sent that argument
    }
}


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class loader {

    public BufferedImage load(String path){
        try {
            BufferedImage img = ImageIO.read(new File(path));
            return img;
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("oh no!"); //testing if image actually got there for myself
        return null;
    }

}

1 个答案:

答案 0 :(得分:2)

这里有很多问题:

  • 您正试图直接在JFrame中绘制,这是您应该避免做的事情,因为JFrame绘画负责这么多,并且在不需要法院麻烦的情况下覆盖它。
  • 而是像教程所指出的那样:在JPanel的paintComponent方法中绘制,并将该JPanel放在JFrame中。
  • 同样按教程指出:在你的覆盖中调用超级绘画方法。
  • 你正在从绘画方法中读取一个图像,这也是一件坏事,一个不必要地多次读取图像,并且不必要地减慢绘画速度。
  • 在显示GUI(如果可能)之前,先阅读一次中的图像,然后放入字段中。然后在检查null之后在paintComponent方法中绘制它。
  • 您的g.drawImage(...)方法错误,错误的地方为null。避免使用null,而是将this放入最后一个参数。
  • 您使用线程是可疑的。至少将您的GUI代码排在Swing事件线程上。
  • 同样,我不能重复:阅读有关这方面的教程,因为在阳光下没什么新东西。向专家学习。

例如:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class ShowingImage extends JPanel {
    private BufferedImage myImage; // variable to hold reference to image

    public ShowingImage(BufferedImage img) {
        this.myImage = img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        // first call super method to do "house-keeping" drawing 
        super.paintComponent(g);
        if (myImage != null) {
            // if the image isn't null, draw it
            g.drawImage(myImage, 0, 0, this);
        }
    }

    // size our GUI based on the image size
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || myImage == null) {
            return super.getPreferredSize();
        }
        int w = myImage.getWidth();
        int h = myImage.getHeight();
        return new Dimension(w, h);
    }


    private static void createAndShowGui(BufferedImage img) {
        ShowingImage mainPanel = new ShowingImage(img);

        JFrame frame = new JFrame("ShowingImage");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // the image path below must contain a path to image file relative to the class files location
        String imagePath = "";  // TODO: fix this with real path!

        URL imageUrl = ShowingImage.class.getResource(imagePath);
        try {
            final BufferedImage image = ImageIO.read(imageUrl);

            // start GUI on the Swing event thread
            SwingUtilities.invokeLater(() -> createAndShowGui(image));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

请查看代码中的注释。上面的代码不完整,只有在您更改行String imagePath = "";以使其包含指向相对于类文件路径的图像路径的String 之后才会生效。您可能希望从其中一个类包目录创建一个子目录,并可能将其称为图像,并将应用程序的图像放在那里。