如何在 java 的另一个线程中绘制 gif?

How to draw a gif in another thread in java?

这是我第一次尝试在 java 中使用另一个线程,有人可以告诉我如何让它工作吗?我已经阅读了其他关于它的主题,但我没有找到解决方案。

我想在另一个线程中绘制 gif(在随机位置和动画持续期间绘制)。

问题是第二个线程中的 drawImage() 什么也没做。我的计数器工作正常(它打印 1.. 2.. 3 ...),但没有绘制图像(或者我看不到)。

条件一开始为假,然后在某一时刻为真(只创建一个新线程,不再创建),然后再次为假。

if (condition) {
    (new ThreadGif(this,g)).start();
}

然而,当我删除 paintComponent() 中的条件时,它会绘制一些东西,这意味着 drawImage() 可以工作。因此,当它创建大量新线程时,gif 的每个图像都被绘制在一个随机位置,并且它一次又一次地启动 gif(并且计数器仍然运行良好)。

这可能没问题,但我不认为创建数千个新线程是答案:我只需要一个。而且,我只需要为每个 gif 设置一个随机位置,而不是为每个 gif 图像设置一个不同的位置。

希望我说得够清楚了。请帮助我了解如何让它工作 :) 非常感谢。

这是我的两个类的简化版本:

ThreadGif.java :

public class ThreadGif extends Thread { 

    Screen screen;
    Graphics g;
    boolean running = true;

    public ThreadGif(Screen screen, Graphics g) {
        this.g = g;
        this.screen = screen;
    }

    public void run() {

        int aleaX = new Random().nextInt(300)/100;
        int aleaY = new Random().nextInt(300)/100;
        int compt = 1;

        while (running) {
            g.drawImage(new ImageIcon("res/feu.gif").getImage(), screen.tailleCase*aleaX, screen.tailleCase*aleaY, screen.tailleCase*2, screen.tailleCase*2, screen);
            System.out.println("thread " + compt);
            compt++;
            try {
                Thread.sleep(sleepTime);
            } catch(InterruptedException e) {
                e.printStackTrace ();
            }
        }
    }       
}

Screen.java :

public class Screen extends JPanel implements Runnable {
    Thread thread = new Thread(this);

    public Screen(Frame frame) {
        this.frame = frame;
        thread.start();
    }

    public void paintComponent(Graphics g) {
        g.clearRect(0, 0, this.frame.getWidth(), this.frame.getHeight());
        if (condition) {
            (new ThreadGif(this,g)).start();
        }
    }

    public void run() { 
        while (running) {
            repaint();
            try {
                Thread.sleep(sleepTime);
            } catch(InterruptedException e) {
                e.printStackTrace ();
            }
        }
        System.exit(0);
    }
}

很简单:您混合了两种方法。
paintComponent 方法在每次被调用时都会启动一个新的 ThreadGif 并且 ThreadGif 本身会在其线程内绘制直到它终止,但不会刷新屏幕。

这两种方法结合起来可能会导致奇怪的行为,例如两幅图像相互重叠绘制,或者新 ThreadGif 每次重新绘制屏幕时只渲染新图像。

解决方案:首先分配每个 class 特定任务,不要混淆任何东西,或将任务拆分到两个 class 之间。例如:

  • ThreadGif 本身不绘制任何东西,而是重新绘制 ScreenScreen可以向ThreadGif请求应该显示的图片。
  • 制作 ThreadGif 一个自己的 Component 来处理它自己的渲染并省略 Screen-class 绘制任何东西。