Java 我无法在JPanel上查看BuffereImage图像
我对下面的代码有问题。如果我将图像直接加载到JPanel中,我可以看到它。但是当我试图在JPanel上绘制BuffereImage之前先将其绘制到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;
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我相信你的答案是正确的。如果你恢复它,我很乐意投票表决。