【问题标题】:I cant view a BufferedImage image on a JPanel我无法在 JPanel 上查看 BufferedImage 图像
【发布时间】:2014-04-08 22:45:28
【问题描述】:

下面的代码有问题。如果我将图像直接加载到 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();
    }

}

【问题讨论】:

  • @Reimeus 我不是故意让你删除你的答案,我的 cmets 只是观察,经过一些测试,我认为你在正确的轨道上......
  • @Reimeus 我相信你的答案是正确的。如果您恢复它,我很乐意为它投票。

标签: java swing jpanel bufferedimage


【解决方案1】:

这件事有些地方不太对劲……

首先,您为BufferedImage 创建了一个Graphics 上下文,但从不创建dispose 的上下文。请注意,在某些系统上,这可能会阻止内容被渲染,但这可能与屏幕设备有关,而不是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.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;
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多