Java 我无法在JPanel上查看BuffereImage图像

Java 我无法在JPanel上查看BuffereImage图像,java,swing,jpanel,bufferedimage,Java,Swing,Jpanel,Bufferedimage,我对下面的代码有问题。如果我将图像直接加载到JPanel中,我可以看到它。但是当我试图在JPanel上绘制BuffereImage之前先将其绘制到BuffereImage时,图像是不可见的。我做错了什么 import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import javax.swing.JFrame; import java.awt.*; import javax.swing.JPanel;

我对下面的代码有问题。如果我将图像直接加载到JPanel中,我可以看到它。但是当我试图在JPanel上绘制BuffereImage之前先将其绘制到BuffereImage时,图像是不可见的。我做错了什么

import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.JPanel;

/**
 *
 * @author Duafeb
 */
public class RTester {
    BufferedImage backBuffer;
    Graphics2D g2;
    Pane pain;
    Image img;




    public RTester(){
        JFrame frame=new JFrame("Sprite Tester");
        frame.setSize(1200, 700);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        backBuffer= new BufferedImage(1200,700,BufferedImage.TYPE_INT_RGB);
        g2=backBuffer.createGraphics();
        pain=new Pane();
        frame.add(pain);
        Toolkit tk=Toolkit.getDefaultToolkit();
        img=tk.getImage(this.getClass().getResource("running.png"));


        frame.setVisible(true);
    }
      public class Pane extends JPanel{
        @Override
        public void paintComponent(Graphics g){
            Graphics2D g3=(Graphics2D)g;
            g3.drawImage(backBuffer, 0, 0, this);

        }
    }     

      public void display(){
          g2.setColor(Color.yellow);
          g2.fillRect(0, 0, pain.getWidth(), pain.getHeight());
          g2.drawImage(img, 0, 0, pain);
          pain.repaint();
      }
    public static void main(String[] args){
        RTester test=new RTester();
        test.display();
    }

}

有几件事让我觉得不对劲

第一种方法是,创建
图形
上下文以
缓冲图像
,但决不
处理它。请注意,在某些系统上,这可能会阻止内容被呈现,但这可能与屏幕设备有关,而不是与
BufferedImage

例如,如果我将代码更改为直接在
paintComponent
方法中绘制内容,而不是在
BufferedImage
中绘制内容,则将显示图像(在窗口变为可见后的一瞬间显示所有位)

我不确定使用
BufferedImage
要实现什么,但您可以直接通过
paintComponent
方法实现同样的目标

您可以使用
ImageIO.read
,而不是使用
Toolkit.getImage
,它可以保证当图像返回时,图像已完全加载(或者如果失败,将抛出
IOException
),或者按照@Reimeus先前的建议,在继续使用图像之前,请使用
MediaTracker
确保图像已正确加载

所以,你有四个选择

一个 使用
MediaTracker
等待图像加载

MediaTracker mt = new MediaTracker(frame);
mt.addImage(img, 1);
try {
    mt.waitForAll();
} catch (InterruptedException ex) {
    ex.printStackTrace();
}
两个 使用
ImageIO。改为阅读

img = ImageIO.read(this.getClass().getResource("running.png"));
三 直接在
paintComponent
方法中渲染输出

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g3 = (Graphics2D) g;
    g3.setColor(Color.yellow);
    g3.fillRect(0, 0, pain.getWidth(), pain.getHeight());
    g3.drawImage(img, 0, 0, obsever);
}
四 使用您自己的
ImageObserver
确保在更新图像时,将其重新渲染到备份缓冲区

private MyImageObsever obsever;

public void display() {
    if (obsever == null) {
        obsever = new MyImageObsever(this);
    }
    g2.setColor(Color.yellow);
    g2.fillRect(0, 0, pain.getWidth(), pain.getHeight());
    g2.drawImage(img, 0, 0, obsever);
    pain.repaint();
}

public class MyImageObsever implements ImageObserver {

    private RTester tester;

    public MyImageObsever(RTester tester) {
        this.tester = tester;
    }

    @Override
    public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
        tester.display();
        return (infoflags & (ALLBITS|ABORT)) == 0;
    }

}

@Reimeus我不是想让你删除你的答案,我的评论只是观察,经过一些测试,我认为你在正确的轨道上…@Reimeus我相信你的答案是正确的。如果你恢复它,我很乐意投票表决。