Threads, Doppelpufferung --> Beispiel gefunden, geht net

  • Themenstarter Themenstarter jb_Noob
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
J

jb_Noob

Gast
Hallo,
ich mach grad das Tutorial
java in 21 Tagen durch: Kap 10 http://jerry.c-lab.de/java/21Tage/kap10.htm#E28E13

Dabei gibt es am Ende des Kapitels Folgenden Code:

Code:
import java.awt.Graphics;

 import java.awt.Color;

 import java.awt.Image;

 public class Checkers2 extends java.applet.Applet implements Runnable {
   Thread runner;
  int xpos;
  Image offscreenImg;
   Graphics offscreenG;
  public void init() {
     offscreenImg = createImage(this.size().width, this.size().height);
     offscreenG = offscreenImg.getGraphics();
   }
  public void start() {
     if (runner == null); {
       runner = new Thread(this);
       runner.start();
     }
   }
  public void stop() {
     if (runner != null) {
       runner.stop();
       runner = null;
     }
   }
   public void run() {
     while (true) {
       for (xpos = 5; xpos <= 105; xpos+=4) {
         repaint();
         try { Thread.sleep(100); }
         catch (InterruptedException e) { }
      }
      xpos = 5;
     }
   }
   public void update(Graphics g) {
      paint(g);
   }
   public void paint(Graphics g) {
     // Hintergrund zeichnen
     offscreenG.setColor(Color.black);
     offscreenG.fillRect(0,0,100,100);
     offscreenG.setColor(Color.white);
     offscreenG.fillRect(100,0,100,100);
     // Oval zeichnen
     offscreenG.setColor(Color.red);
     offscreenG.fillOval(xpos,5,90,90);
     g.drawImage(offscreenImg,0,0,this);
   }
   public void destroy() {
      offscreenG.dispose();
   }
}

Der geht jedoch nicht, es kommt immer folgender Fehler:

Exception in thread "main" java.lang.NullPointerException
at moveladystone.Ladystone.init(Ladystone.java:15)
at com.borland.jbuilder.runtime.applet.AppletTestbed.startApplet(Unknown Source)
at com.borland.jbuilder.runtime.applet.AppletTestbed.main(Unknown Source)



in der init - Methode wird folgende Zeile ( Zeile 14) Markiert

--> offscreenG = offscreenImg.getGraphics();


Mach ich irgend was falsch??

Schonmal danke
Noob


PS:
ich benutze jBuilder 6
 
Der Fehler wird offenbar durch die size()-Methode in Zeile 13 ausgelöst. Sie ist deprecated und liefert möglicherweise die falschen Werte.
Des Weiteren ist das DoubleBuffering nicht korrekt implementiert. Die update()-Methode dient dazu, im Hintergrund des Geschehens ein Bild vorzubereiten, welches dann letztendlich auf die Bildfläche kopiert wird. Die paint()-Methode setzt also das Bild nicht mehr zusammen sondern zeichnet nur noch ein Bild.
Außerdem ist die stop()-Methode aus Thread deprecated und sollte durch etwas, wie in meinem Beispiel ersetzt werden.

Code:
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;

public class Checkers2 extends java.applet.Applet implements Runnable {
   private Thread runner;
   private int xpos;
   private Image offscreenImg;
   private Graphics offscreenG;
   
   public void init() {
      offscreenImg = createImage(this.getSize().width, this.getSize().height);
      offscreenG = offscreenImg.getGraphics();
   }
   
   public void start() {
      if (runner == null) {
         runner = new Thread(this);
      }
      runner.start();
   }

   public void stop() {
      if (runner != null) {
         runner.interrupt();
         runner = null;
      }
   }
   public void run() {
      while (!runner.interrupted()) {
         for (xpos = 5; xpos <= 105; xpos+=4) {
            repaint();
            try {
               Thread.sleep(50);
            }
            catch (InterruptedException e) {
               runner.interrupt();
            }
         }
         xpos = 5;
      }
   }
   
   public void update(Graphics g) {
      // Hintergrund zeichnen
      offscreenG.setColor(Color.black);
      offscreenG.fillRect(0,0,100,100);
      offscreenG.setColor(Color.white);
      offscreenG.fillRect(100,0,100,100);
      // Oval zeichnen
      offscreenG.setColor(Color.red);
      offscreenG.fillOval(xpos,5,90,90);
      g.drawImage(offscreenImg,0,0,this);
   }
   
   public void paint(Graphics g) {
      g.drawImage(offscreenImg,0,0,this);
   }
}
 
Danke erstmal,
durch deine Antwort hat sich ein älteres Problem das ich mit nem Anderen Programm hatte in Luft aufgelöst :toll:


Nur leider bekomm ich beim aktuellen Problem imer noch die gleiche Fehlermeldung:

Beim Kompilieren meckert der Kompiler folgendes:
Hit Nicht behandelte Exception java.lang.NullPointerException

Ich kann mir da aber kein reim draus machen,

mit offscreenImg = createImage(this.getSize().width, this.getSize().height); und danach
offscreenG = offscreenImg.getGraphics();
übergibt man iffscreenG doch die Fenstergröße??


Zu erwähnen ist noch, dass das Beispiel nicht mit getSize() sondern mit size() angegeben war.
Vielleicht hab ich ja mit getSize irgendwas falsch gemacht.

Hier nochmal die Init Methode:

Code:
public void init() {
      offscreenImg = createImage(this.getSize().width, this.getSize().height);
      offscreenG = offscreenImg.getGraphics(); //HIER WIRD GEMECKERT
   }


@SebiB90: Das beispiel war der Aktuelle Versuch, hab nochmal einen mit den Verbesserungen von L-ectron-X
gemacht --> immer noch der gleiche Fehler

Gruß
Noob


PS:
Hier nochmal der Ganze Code wie ich'n in jBuilder eingegeben habe:

Code:
package dame;


import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;

public class Checkers2 extends java.applet.Applet implements Runnable {
   private Thread runner;
   private int xpos;
   private Image offscreenImg;
   private Graphics offscreenG;

   public void init() {
      offscreenImg = createImage(this.getSize().width, this.getSize().height);
      offscreenG = offscreenImg.getGraphics();
   }

   public void start() {
      if (runner == null); {
         runner = new Thread(this);
      runner.start();
   }
}
   public void stop() {
      if (runner != null) {
         runner.interrupt();
         runner = null;
      }
   }
   public void run() {
      while (!runner.interrupted()) {
         for (xpos = 5; xpos <= 105; xpos+=4) {
            repaint();
            try {
               Thread.sleep(50);
            }
            catch (InterruptedException e) {
               runner.interrupt();
            }
         }
         xpos = 5;
      }
   }

   public void update(Graphics g) {
      // Hintergrund zeichnen
      offscreenG.setColor(Color.black);
      offscreenG.fillRect(0,0,100,100);
      offscreenG.setColor(Color.white);
      offscreenG.fillRect(100,0,100,100);
      // Oval zeichnen
      offscreenG.setColor(Color.red);
      offscreenG.fillOval(xpos,5,90,90);
      g.drawImage(offscreenImg,0,0,this);
   }

   public void paint(Graphics g) {
      g.drawImage(offscreenImg,0,0,this);
   }
}
 
Bei mir läuft das Applet ohne Probleme, obwohl ein kleiner, unwichtiger Fehler drinne ist:
Code:
  public void start() {
     if (runner == null) { // So sollte es aussehen nicht: if (runner == null); {
       runner = new Thread(this);
       runner.start();
     }
   }

Wie lädst du denn das Applet?
 
Das Semikolon habe ich doch glatt übersehen... :shock:

Wie sieht denn dein HTML-Code aus? Die getSize()-Methode ermittelt die Größe des Applets. Vielleicht hast du die Attribute dafür in deinem Applet-Tag vergessen.
Bei mir läuft das Applet jedenfalls.

Ich habe die start()-Methode nochmal korrigiert, denn so ^^ ist sie auch verkehrt.
Code:
public void start() { 
   if (runner == null) { 
      runner = new Thread(this);  
   }
   runner.start(); 
}
 
Hallo,
Danke , aber auch am semi - colon lags nicht.

Ich hab
offscreenImg = createImage(this.getSize().width, this.getSize().height); mal durch
offscreenImg = createImage(500, 400); ersetzt, ---> kein erfolg

Wenn ich das offscreenG Objekt durch das Graficsobject ersetze Ggehts einwandfrei
z.B.
in update()
statt offscreenG.setColor(Color.black);
eben g.setColor(Color.black);

dann zappelt das Bild halt wieder.

Aber das sagt zumindest dass irgendwas mit offscreen schief läuft.


The return value may be null if the component is not displayable. This will always happen if GraphicsEnvironment.isHeadless() returns true.
Returnwert wird null sein, wenn GraphicsEnvironment.isHeadless() null zurückgibt????
Was genau bedeutet das, und wie behebe ich das???

Hier mal das ganze Packet:


code:
Code:
package dame;


import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;

public class Checkers2 extends java.applet.Applet implements Runnable {
   private Thread runner;
   private int xpos;
   private Image offscreenImg;
   private Graphics offscreenG;

   public void init() {
      offscreenImg = createImage(this.getSize().width, this.getSize().height);
      offscreenG = offscreenImg.getGraphics();
   }

   public void start() {
      if (runner == null) {
         runner = new Thread(this);
      runner.start();
   }
}
   public void stop() {
      if (runner != null) {
         runner.interrupt();
         runner = null;
      }
   }
   public void run() {
      while (!runner.interrupted()) {
         for (xpos = 5; xpos <= 105; xpos+=4) {
            repaint();
            try {
               Thread.sleep(50);
            }
            catch (InterruptedException e) {
               runner.interrupt();
            }
         }
         xpos = 5;
      }
   }

   public void update(Graphics g) {
      // Hintergrund zeichnen
      offscreenG.setColor(Color.black);
      offscreenG.fillRect(0,0,100,100);
      offscreenG.setColor(Color.white);
      offscreenG.fillRect(100,0,100,100);
      // Oval zeichnen
      offscreenG.setColor(Color.red);
      offscreenG.fillOval(xpos,5,90,90);
      g.drawImage(offscreenImg,0,0,this);
   }

   public void paint(Graphics g) {
      g.drawImage(offscreenImg,0,0,this);
   }
}


HTML:

<html>
<head>
<title>
HTML-Testseite
</title>
</head>
<body>
dame.Checkers2 erscheint in einem Java-fähigen Browser.

<applet
codebase = "."
code = "dame.Checkers2.class"
name = "TestApplet"
width = "500"
height = "400"
hspace = "0"
vspace = "0"
align = "middle"
>
</applet>
</body>
</html>
 
Ich bin am verzweifeln :bahnhof:

Was zum Donnerwetter nochmal läuft hier schief :?: ???:L :?:

Hab nen Neues, Kleineres, Übersichtlicheres Programm, ohne Threading und schnick schnack geschrieben.

Alles so gemacht, wies in allen Tutorials die ich gecheckt habe publiziert wurde!

Immer wieder die gleiche Fehlermeldung (in Zeile 12)! :cry: :cry: :cry:

Hier mein neues Programm, mit HTML und den Fehlermeldungen:

Code:
package test_douplepounding;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class Buffering extends Applet {
    Image offscreenImage;
    Graphics offscreenGraphics;
public void init(){
    offscreenImage = createImage(250, 251);
    offscreenGraphics = offscreenImage.getGraphics();
}


    public void update(Graphics g){
        offscreenGraphics.drawLine(10,20,100,200);
        offscreenGraphics.drawLine(100,200,60,100);
        offscreenGraphics.drawLine( 60, 100, 10, 20 );
        if (offscreenImage != null)
            g.drawImage(offscreenImage,0,0,this);
    }

    public void paint(Graphics g){

        if (offscreenImage != null)
            g.drawImage(offscreenImage,0,0,this);
    }

}

<html>
<head>
<title>
HTML-Testseite
</title>
</head>
<body>
test_douplepounding.Buffering erscheint in einem Java-fähigen Browser.

<applet
codebase = "."
code = "test_douplepounding.Buffering.class"
name = "TestApplet"
width = "400"
height = "300"
hspace = "0"
vspace = "0"
align = "middle"
>
</applet>
</body>
</html>



Nach Compilieren:
Hit Nicht behandelte Exception java.lang.NullPointerException

nach ausführen:
Exception in thread "main" java.lang.NullPointerException
at test_douplepounding.Buffering.init(Buffering.java:12)
at com.borland.jbuilder.runtime.applet.AppletTestbed.startApplet(Unknown Source)
at com.borland.jbuilder.runtime.applet.AppletTestbed.main(Unknown Source)



ich weiß nicht mehr weiter...


BITTE HELFEN :cry:

Anfänger alias noob
 
Ähm selber geschafft, war eh nen Müll, hier braucht man kein Update() :lol:


Eine Frage brennt mir dann aber doch noch unter den Nägeln:


Wie kommt das:

So gibts ne Fehlermeldung:

Code:
public class Buffering extends Applet {
    Image offscreenImage;
    Graphics offscreenGraphics;

public void init(){
    offscreenImage = createImage(250, 251);
    offscreenGraphics = offscreenImage.getGraphics();
}
    public void paint(Graphics g){
        offscreenGraphics.drawLine(10,20,100,200);
        offscreenGraphics.drawLine(100,200,60,100);
        offscreenGraphics.drawLine( 60, 100, 10, 20 );
        if (offscreenImage != null)
            g.drawImage(offscreenImage,0,0,this);
    }

}

so gehts problemlos:

Code:
public class Buffering extends Applet {
    Image offscreenImage;
    Graphics offscreenGraphics;

    public void paint(Graphics g){
        //Initialisieren
        offscreenImage = createImage(250, 251);
        offscreenGraphics = offscreenImage.getGraphics();
        //Ausführen
        offscreenGraphics.drawLine(10,20,100,200);
        offscreenGraphics.drawLine(100,200,60,100);
        offscreenGraphics.drawLine( 60, 100, 10, 20 );
        if (offscreenImage != null)
            g.drawImage(offscreenImage,0,0,this);
    }
}

Warum??
Hab ich irgendwelche Objekte, Zugriffsrechte o.ä. vergessen/verletzt??

Init() ist doch für applets da, warum geht dann die erste Lösung aber nicht??


Gruß
Dazugelernter
 
Was für eine Exception? :roll:
So kann ich nur in die Glaskugel schauen:
Du bekommst eine NullPointerException weil zum init() Zeitpunkt das Applet noch nicht displayable ist und daher createImage noch nicht funktioniert.
Deine 'Lösung' ist übrigens der Performancetod :noe:
 
Probier mal das:

Code:
public class Buffering extends Applet { 
    Image offscreenImage; 
    Graphics offscreenGraphics; 

public void init(){ 
    offscreenImage = createImage(250, 251); 
    offscreenGraphics = offscreenImage.getGraphics(); 
} 
    public void paint(Graphics g){ 
        if (offscreenImage != null)    // <-------     schau mal hier!!!!!
        {
            offscreenGraphics.drawLine(10,20,100,200); 
            offscreenGraphics.drawLine(100,200,60,100); 
            offscreenGraphics.drawLine( 60, 100, 10, 20 ); 
                                                    // nicht mehr hier.
            g.drawImage(offscreenImage,0,0,this); 
        }
    } 

}
 
Erstmal ganz großen dank an alle die hier Antworten :roll:


Wildcard hat gesagt.:
Du bekommst eine NullPointerException weil zum init() Zeitpunkt das Applet noch nicht displayable ist und daher createImage noch nicht funktioniert.

Und wie kann ich das ändern??? ???:L :bahnhof: :?:



Hier nochmal Code + Fehlermeldungen

Code:
package test_douplepounding;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class Buffering extends Applet {
    Image offscreenImage;
    Graphics offscreenGraphics;

public void init(){
    //Image und Zeichenfläche Initialisieren
    offscreenImage = createImage(250, 250);
    offscreenGraphics = offscreenImage.getGraphics();
}
    public void paint(Graphics g){
        //Ausführen
        if (offscreenImage != null)    //Auch mit if-Anweisung hier gehts nicht
        {
            offscreenGraphics.drawLine(10,20,100,200);
            offscreenGraphics.drawLine(100,200,60,100);
            offscreenGraphics.drawLine( 60, 100, 10, 20 );
            g.drawImage(offscreenImage,0,0,this);
        } 
    }
}

Meldungen:
1.
Hit Nicht behandelte Exception java.lang.NullPointerException
2.
Exception in thread "main" java.lang.NullPointerException
at test_douplepounding.Buffering.init(Buffering.java:14)
at com.borland.jbuilder.runtime.applet.AppletTestbed.startApplet(Unknown Source)
at com.borland.jbuilder.runtime.applet.AppletTestbed.main(Unknown Source)


Wildcard hat gesagt.:
Was für eine Exception?
Ich wiß nichtmal was der compiler mit exception meint, der markiert nur jedesmal Zeile 14 !


Danke und Gruß
 
so sollte es gehen:
Code:
public class Buffering extends Applet {
    Image offscreenImage;
    Graphics offscreenGraphics;

public void init(){

}
    public void paint(Graphics g){
        if(offscreenImage==null){
          offscreenImage = createImage(250, 251);
          offscreenGraphics = offscreenImage.getGraphics();
        }
        offscreenGraphics.drawLine(10,20,100,200);
        offscreenGraphics.drawLine(100,200,60,100);
        offscreenGraphics.drawLine( 60, 100, 10, 20 );
        if (offscreenImage != null)
            g.drawImage(offscreenImage,0,0,this);
    }

}
 
ich würds nicht in die paint methode packen
pack es in die start() methode, die wird nach init() aufgerufen und zu dem zeitpunkt sollte das applet displayable sein.
 
Danke 😀 :toll: 😀

Jetzt gehts, das alte LadyStone und das neue 😀 😀


Eins frag ich mich aber noch, ist das immer so, dass beim init() das applet noch displayable ist, oder ist das Zufallssache??

Weil in 2 Tutorials (Java in 21 Tagen, Galileo Computing) wurde das mit Init() erklärt, und die müssens ja mal ausprobiert haben??


Gruß
NochMehrGelernter 😀
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben