在多线程中使用awt Paint

时间:2010-10-17 09:36:07

标签: java multithreading paint

我有一个学校项目,我想把它献给新年,我提出的项目是Text-Firework,我使用角色和符号作为Explosion粒子,并且不断改变他们的X和Y位置在Paint()中。  我对如何一起使用Paint和Thread感到困惑。问题是它不是在屏幕上绘画,也可能是线程没有启动。 (我真的不能告诉我,对不起)。问题是我没有得到任何错误,它只是不起作用:(

我认为代码有点长,谢谢你阅读它。

应该如何工作:当用户点击时,将在鼠标位置启动Firework线程, 这个Firework类有一个绘制循环,用于重新创建增量爆炸。所以基本上,我希望用户创建多个爆炸,这就是为什么我把它变成一个线程。

这是主applet:

public class TBFireworks extends Applet implements MouseListener
{
    public void init()
    {
        setBackground( Color.black );
        addMouseListener( this );
    }

    public void mouseEntered( MouseEvent e ) { }
    public void mouseExited( MouseEvent e ) { }
    public void mousePressed( MouseEvent e ) { }
    public void mouseReleased( MouseEvent e ) { }
    public void mouseClicked( MouseEvent e ) 
    {
        new Firework( e.getX(),e.getY(), this);
    }
}

和Firework Thread类:

class Firework extends Thread
{
    Point center = new Point(0,0);
    int blastRadius = 10;
    Point posIncrement = new Point(0,0);
    Applet applet;

    public Firework(int positionX, int positionY, Applet apple)
    {
        center.x = positionX;
        center.y = positionY;
        applet = apple;
        new Thread(this).start();
    }

    public void run()
    {
        while(blastRadius > 0)
        {
            applet.paint(applet.getGraphics());

            try {
                this.sleep(1000/20);
            } catch (InterruptedException e) { ; }
        }
    }

    public void paint(Graphics g)
    {
        if(blastRadius > 0)
        {
            Point[] fakeFire = {new Point(20,20),new Point(20,30),new Point(30,20)};
            ApplyNextPos(fakeFire,posIncrement);

            g.setColor(Color.red);
            for(int xaa=1; xaa<5; xaa++) // draw the formation
            {
                for(int zaa=0;zaa<fakeFire.length;zaa++)
                {
                    fakeFire[zaa] = GetQuadrant(xaa,center,fakeFire[zaa]);
                }

                for(int yaa=0;yaa<fakeFire.length;yaa++)
                {
                    g.drawString("*",fakeFire[yaa].x,fakeFire[yaa].y);
                }
            }
            posIncrement.incrementPos(5);
            blastRadius--;
        }
    }
}

2 个答案:

答案 0 :(得分:0)

首先,您似乎没有在FireWork线程中使用paint-method,而是调用applet的paint方法。

我在applet和AWT中有点不错,但如果它是Swing(我猜它没有那么不同),我会建议另一种方法。绘画应该(可以?)只能在EDT(事件调度线程)中完成。当用户单击时,您将向FireWork创建一个类似的对象,并将其添加到列表中。然后你开始一个线程(如果还没有启动,在某个面板上不断调用重绘。然后在面板的paint-method中循环所有烟花的列表并绘制它们。

这也会提高内存效率,因为你只使用一个线程。

答案 1 :(得分:0)

当需要(重新)绘制相应的组件或部分时,GUI({1}}方法应该(通常)仅由GUI调用。它不应该由应用程序调用(如果不是从另一个paint方法内部调用)。

调用paint方法来绘制组件的实际状态。状态应该由另一个方法/线程更改。通过调用paint重新绘制组件强制

一个未完整的未经测试的例子:

repaint