我遇到以下代码的问题。如果我将图像直接加载到JPanel中,我可以看到它。但是当我在JPanel上绘制BufferedImage之前尝试先将其绘制到BufferedImage时,图像不可见。我做错了什么?
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();
}
}
答案 0 :(得分:1)
有一些事情对此感觉不正确......
首先,您为Graphics
创建BufferedImage
上下文,但从不dispose
。{请注意,在某些系统上,这可能会阻止内容呈现,但这可能与屏幕设备有关,而不是BufferedImage
例如,如果我改变您的代码以直接在paintComponent
方法而不是BufferedImage
内绘制内容,则会显示图像(在窗口变为可见之后,所有位都会瞬间显示) )。
我不确定您使用BufferedImage
尝试实现的目标,但您可以直接通过paintComponent
方法实现同样的目标
您可以使用Toolkit.getImage
,而不是使用ImageIO.read
,这可以保证在返回时,图像已完全加载(如果失败则会抛出IOException
)或@ Reimeus之前建议使用MediaTracker
确保在继续使用之前正确加载图像。
所以,你有四种选择......
使用MediaTracker
等待加载图片...
MediaTracker mt = new MediaTracker(frame);
mt.addImage(img, 1);
try {
mt.waitForAll();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
使用ImageIO.read
代替......
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;
}
}