java - 在java中绘制图像的奇怪行为

标签 java drawimage

我正在通过在前一个图像之后数十毫秒绘制不同的图像来制作动画。像这样的东西:

 drawimage(image1,0,0,null);

 try {

   Thread.sleep(100);

 }catch(Exception e){//To do something

 }

 drawimage(image2,0,0,null);

但是第一个图像直到第二个图像出现才显示。这意味着它们同时出现。

我的问题是为什么会发生这种情况?

最佳答案

Me: Where exactly is this code? Is it in a paint/paintComponent method?

OP: it is in paintComponent. I use it to make animation, but I am not sure it is a good way.

你是对的,这不是一个好方法。 永远不要打电话 Thread.sleeppaintComponent方法。我会避免 Thread.sleep一起使用 javax.swing.Timer 。查看更多How to Use Swing Timers

查看示例 herehereherehere .

你可以...

使用 listImages以及 Timer 的每次迭代触发事件,添加另一个 ImageList<Image>并调用repaint()

你可以...

有一个MyImage具有 Image 的对象类场和一个boolean draw field 。在计时器中,循环MyImage对象并执行类似的操作

    for (MyImage image: images) {
        if (!image.isDraw()) {
            image.setDraw(true);
            break;
        }
    }
    repaint();

对于MyImage List只需在 paintComponent 中循环遍历它们即可方法并调用它 drawImage方法,您创建的。

<小时/>

运行此示例,显示第一个选项

enter image description here

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class AnimateImages extends JPanel {
    private static final int IMAGE_ROWS = 10;
    private static final int IMAGE_COLS = 10;
    private static final int IMAGE_SIZE = 50;
    private static final int DIM_WIDTH = IMAGE_COLS * IMAGE_SIZE;
            
    private final List<MyImage> images;
    private Image image;
    private int currX = -IMAGE_SIZE;
    private int currY;
    
    public AnimateImages() {
        try {
            image = ImageIO.read(new URL("http://swoo.co.uk/content/images/icons/stackoverflow.png"));
        } catch (IOException ex) {
            Logger.getLogger(AnimateImages.class.getName()).log(Level.SEVERE, null, ex);
        }
        images = createImages();
        
        Timer timer = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (MyImage image : images) {
                    if (!image.isDraw()) {
                        image.setDraw(true);
                        break;
                    }
                    repaint();
                }
            }
        });
        timer.start();
    }
    
    private List<MyImage> createImages() {
        List<MyImage> list = new ArrayList<>();
        for (int i = 0; i < IMAGE_ROWS * IMAGE_COLS; i++) {
            if (currX >= DIM_WIDTH) {
                currX = 0;
                currY += IMAGE_SIZE;
            } else {
                currX += IMAGE_SIZE;
            }
            list.add(new MyImage(image, currX, currY));
            
        }
        return list;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (MyImage img : images) {
            img.draw(g);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(IMAGE_SIZE * IMAGE_COLS, IMAGE_SIZE * IMAGE_ROWS);        
    }

    public class MyImage {

        Image image;
        int x, y;
        boolean draw = false;

        public MyImage(Image image, int x, int y) {
            this.image = image;
            this.x = x;
            this.y = y;
        }

        public void setDraw(boolean draw) {
            this.draw = draw;
        }

        public boolean isDraw() {
            return draw;
        }

        public void draw(Graphics g) {
            if (draw) {
                g.drawImage(image, x, y, IMAGE_SIZE, IMAGE_SIZE, AnimateImages.this);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new AnimateImages());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

关于java - 在java中绘制图像的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22342876/

相关文章:

java - Java中如何使用String对象解析输入

java - 我应该为 Graphics.drawImage() 函数的 ImageObserver 参数使用 null 吗?

c# - Winform 闪烁问题

android - 带有视频源的 HTML5 Canvas drawImage 不适用于 Android

java - 沿着标记移动相机

java - startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION) 上出现 NullPointException;

java - Apache 德鲁伊 没有已知的服务器

java - svg 文件在 android 中呈现

javascript - 使用 javascript 和 jQuery 进行色度键控

Java绘制图像插值