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

如何在java的另一个线程中绘制gif?,java,multithreading,swing,paint,animated-gif,Java,Multithreading,Swing,Paint,Animated Gif,这是我第一次尝试使用java中的另一个线程,有人能告诉我如何使它工作吗?我读过其他关于它的话题,但我没有找到解决办法 我想在另一个线程中绘制gif(在随机位置绘制,并在其动画期间绘制) 问题是第二个线程中的drawImage()什么都不做。我的计数器工作正常(它打印1..2..3…),但没有绘制图像(或者我看不到) 条件在开始时为false,然后在某一时刻为true(只创建一个新线程,不再创建),然后再次为false if (condition) { (new ThreadGif(thi

这是我第一次尝试使用java中的另一个线程,有人能告诉我如何使它工作吗?我读过其他关于它的话题,但我没有找到解决办法

我想在另一个线程中绘制gif(在随机位置绘制,并在其动画期间绘制)

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

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

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
仅渲染新图像

解决方案:从分配每个类特定的任务开始,不要混淆任何内容,也不要在两个类之间拆分任务。例如:

  • ThreadGif
    本身不绘制任何内容,而是重新绘制
    屏幕
    屏幕可以从
    ThreadGif
    请求应显示的图像
  • 使
    ThreadGif
    成为自己的
    组件
    ,处理自己的渲染,并使
    屏幕
    -类不绘制任何内容

在Swing事件线程中禁用paintComponent图形参数的情况下进行绘制闻起来像是在邀请线程灾难,不是吗?难道不是相反吗?--创建一个具有自己内部计时器的
SwingWorker
,在SwingWorker中创建图像,通过发布/处理方法对将图像导出到GUI,然后调用repaint?@HovercraftFullOfEels,如何/何时刷新屏幕是另一个问题
SwingWorker
将是一个选项,但这取决于我的意见。感谢您的回答:)如果条件为真,则paintComponent只会启动一个新的线程GIF,这种情况只会发生一次。我试着不看它是否能画出什么东西,但我知道这是个坏主意。事实上,你所描述的必须是在没有条件的情况下发生的事情。但是当我只创建一个新线程时,为什么它不起作用呢?为您提供的解决方案:第一个:我创建了ThreadGif类,因为在Screen.paintComponent()中绘制gif太难了。它没有其他用途。“屏幕可以请求图像…”是什么意思?你能多说一点吗?第二个一:第二个一:我不知道该怎么办对不起,我真的不知道组件是什么,我需要调查一下。我是初学者。@Dreamk33中的“屏幕可以请求图像…”我的意思是您可以向
ThreadGif
-类添加一个getter,该类返回调用getter时应绘制的图像。至于第二个:基本上,我的意思是可以合并
ThreadGif
Screen
-类,因为它们显然是1:1的关系。因此,让
Screen
启动自己的线程来更新图像,而不是将此部分留给单独的类。但总的来说:为什么你甚至需要一根线?您的代码只会一遍又一遍地绘制同一个图像。在Swing事件线程中禁用paintComponent图形参数进行绘制闻起来像是在邀请线程灾难,不是吗?难道不是相反吗?--创建一个具有自己内部计时器的
SwingWorker
,在SwingWorker中创建图像,通过发布/处理方法对将图像导出到GUI,然后调用repaint?还有以下内容:
g.drawImage(新图像图标(“res/feu.gif”).getImage()已损坏。为什么要一遍又一遍地重读同一个图像,而只读入一次并将其存储到变量中更简单、更经济呢?我将搜索SwingWork谢谢。是的,我绝对同意,我正在改变它。