Avatar billede driis Nybegynder
28. februar 2004 - 19:38 Der er 11 kommentarer og
2 løsninger

Tråd, der animerer en bold i en JApplet

Jeg er i gang med at lave et ret simpelt animationsprogram i Java. Tanken var at lave en JApplet, der starter en tråd, som så med et bestemt interval tegner noget ved hjælp af applet'ens Graphics objekt. Imidlertid får jeg en:

java.lang.NullPointerException

    at øv7.BallAnimatingThread.run BallAnimatingThread.java:54)

Når jeg prøver at bruge Graphics.
Koden er som følger:


package øv7;

import java.awt.*;
import javax.swing.*;

/**
* Animerer en bold i et JApplet vindue
*
* @author Dennis Riis
* @version 1.0
*/
public class BallAnimatingThread extends StoppableThread
{
    /**
    * Starter animation på <code>destination</code>, en bold med størrelse
    * <code>ballSize</code> og hastighed <code>speed</code>
    * @param destination Destination JApplet
    * @param ballSize I pixels
    * @param speed Hastighed i pixels/second
    */
    public BallAnimatingThread(JApplet destination, int ballSize, int speed)
    {
        dest = destination;
        size = ballSize;
        pos = new Point(ballSize,ballSize);
        dp = new Point(5,5);
        if ( speed > 0 )
        {
            updSpeed = (speed * 1000) / 5;
        }else
        {
            updSpeed = 200 ;
        }
           
        // Start tråden med det samme.
        start();
    }
   
    /**
    * Tråd startpunkt
    */
    public void run()
    {
        Color bg = dest.getBackground();
        Rectangle clip;
       
        while (canRun)
        {
            // Hent graphics object hver gang, så vi er sikre på at have de
            // rigtige dimensioner.
            g = dest.getGraphics();
           
            // Slet gammel bold
            g.setColor(bg);
            g.fillOval(pos.x,pos.y,size,size);
           
            // udregn ny position
            pos.x += dp.x;
            pos.y += dp.y;
           
            // find ud af om der skal skiftes retning
            clip = g.getClipBounds();
            if ( pos.x < clip.x || pos.x > clip.x + clip.width )
            {
                dp.x *= -1;
                pos.x += dp.x;
            }
            if ( pos.y < clip.y || pos.y > clip.y + clip.height )
            {
                dp.y *= -1;
                pos.y += dp.y;
            }
           
            // Tegn ny bold med rød farve
            g.setColor(Color.RED);
            g.fillOval(pos.x,pos.y,size,size);
           
            // Vent lidt med at opdatere
            try
            {
                sleep(updSpeed);
            }
            catch (InterruptedException ex)
            {
            }
        }
    }
   
   
    /**
    * Tråden tegner i denne applets clipping rect, sættes af constructor
    */
    protected JApplet dest;
   
    protected Graphics g;
    protected Point pos;
    protected Point dp;
    protected int size;
    protected int updSpeed;
}
Avatar billede driis Nybegynder
28. februar 2004 - 19:42 #1
Og spørgsmålet er: Har jeg gjort noget galt ? Eller kan man ikke tegne på i et JApplet vindue fra en anden tråd ?
Avatar billede conrad Nybegynder
28. februar 2004 - 19:43 #2
Hvorn bliver canRun sat ?
Avatar billede driis Nybegynder
28. februar 2004 - 19:45 #3
Den kommer fra klassen StoppableThread, som klassen arver fra. Det er kun et flag der bruges til at teste, om tråden skal stoppes.
Avatar billede driis Nybegynder
28. februar 2004 - 19:46 #4
(Ovenstpe
Avatar billede conrad Nybegynder
28. februar 2004 - 19:48 #5
hvad er linie 54 i din editor ?
Avatar billede driis Nybegynder
28. februar 2004 - 19:55 #6
g.setColor(bg);
Avatar billede conrad Nybegynder
28. februar 2004 - 20:17 #7
Har lige prøvet og ændre lidt, og det kan ihvertfald godt lade sig gøre at tegne på applet'en fra en tråd
Avatar billede conrad Nybegynder
28. februar 2004 - 20:31 #8
Det virker som om clip er null
System.out.println("hello");
clip = g.getClipBounds();
System.out.println(clip); //er null
Avatar billede _carsten Nybegynder
28. februar 2004 - 21:39 #9
Du skal lige have denne her med, så virker det

getClipBounds() returnerer det clip area som du SELV har defineret

D.v.s definerer clip area enten sådan

            Rectangle clip = new Rectangle(0,0, dest.getWidth(), dest.getHeight());

            // eller sådan

            if(clip == null){
                g.setClip(0,0, dest.getWidth(),dest.getHeight());
                clip = g.getClipBounds();
            }

            if ( pos.x < clip.x || pos.x > clip.x + clip.width )
Avatar billede driis Nybegynder
29. februar 2004 - 12:52 #10
At clip er null er selvfølgelig en fejl. Men koden fejler før det, i linien
g.setColor(bg);

Og fejlen er at 
g = dest.getGraphics();
returnerer null. Men hvordan får jeg så fat i et Graphics objekt i min tråd ?
Avatar billede conrad Nybegynder
29. februar 2004 - 13:09 #11
Med carstens tilføjelse kan jeg fint køre din tråd klasse, så der må være et eller andet galt.

Hvor initialiserer du din BallAnimatingThread ?

Kan det skyldes at din tråd starter før din JApplet selv er initialiseret færdig ?
Avatar billede driis Nybegynder
29. februar 2004 - 13:17 #12
Nu har jeg fundet fejlen. dest.getGraphics returnerer kun et Graphics object hvis vinduet er synligt på skærmen. Derfor går det galt i opstartsfasen, og også hvis man trækker et andet vindue hen over applet vinduet. Jeg har løst det ved kun at opdatere, hvis vinduet er synligt:
if ( g != null )
{
...
}

Fra java dokumentationen for getGraphics:
/**
    * Creates a graphics context for this component. This method will
    * return <code>null</code> if this component is currently not
    * displayable.
    * @return a graphics context for this component, or <code>null</code>
    *            if it has none
    * @see      #paint
    * @since    JDK1.0
    */
Avatar billede _carsten Nybegynder
29. februar 2004 - 13:18 #13
Som conrad siger, får du startet din tråd før din applet er initieret, hvilket gør at 'g' er null

Så du skal altså have flyttet new BallAnimatingThread() længere ned i din kode
så du sikrer at appletten er fuldt initieret.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB