views:

34

answers:

2

Hello everyone, I have a school project and i want to dedicate this for New Year, the project that i came up is a Text-Firework, i am using characters and symbols as the Explosion particles, and just constantly changing their X and Y position inside Paint(). I am confused on how to use Paint and Thread together. The problem is it's not painting on the screen or maybe the thread is not starting. (i cant really tell, im sorry). the problem is i dont get any error, it just doesn't work :(

the code is a little bit long i think, thank you for reading it.

How it should Works: When a user click, a Firework Thread will be started on the mouse position, this Firework class has a paint loop for recreating the incremental explosion. so basically, i want the user to create multiple explosions thats why i made it a Thread.

here is the main 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);
    }
}

and the Firework Thread class:

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--;
        }
    }
}
A: 

First, you seem not to be using your paint-method in the FireWork thread, you call the applet's paint method instead.

I'm a bit rosty in the applet and AWT stuff, but if it were Swing (I guess it not that different), I would suggest another approach. Painting should (can?) only be done in the EDT (Event Dispatch Thread). When the user clicks, you create a similar object to FireWork, and add that to a list. Then you start ONE thread (if not already started, that continously calls repaint on some panel. Then in the paint-method of your panel you loop the list of all fireworks and draw them.

This will also be more memory efficient, since you only use one thread.

Avall
Thank you, i made Paint() in the main class, and every time a Firework is instanced, it will be then put into an ArrayList, the Paint() in main class loops all the ArrayList to paint them. It's now working. thank you!
Clave
Painting **can** be done in any thread, but should be done in the EDT.
Ishtar
A: 

The paint method should (normaly) only be called by the GUI when the corresponding component or part of it needs to be (re-)painted. It should not be called by the application (if not from inside another paint method).

The paint method is called to draw the actual state of the component. The state should be changed by another method/thread. The repainting of the component is forced by calling repaint.

An incomplete, untested example:

public class Animation extends Canvas {

    private final List<Firework> fireworks = new ArrayList<Firework>(); 

    public void start() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    step();
                    Thread.sleep(STEP_TIME);  // InterruptedException ?
                }
            }
        });
        t.start();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for (Firework fw : fireworks)
            fw.draw(g);  // draw the Firework
    }

    private void step() {
        for (Firework fw : fireworks) 
            fw.step();  // update/move the Firework
        repaint();
    }

    // methods for adding/deleting Fireworks, synchronization?
}
Carlos Heuberger