# offscreen Zeichnen



## ADVOAR1 (21. Jan 2007)

Hihi....

Ich habe mir eine Klasse geschrieben, welche etwas zeichnen soll..
Dabei hat diese Klasse eine Funktion, welche ich draw genannt hab.


```
public Graphics draw(Graphics g)
{
g.drawImage(Bild, x,y,width,height,this);
return g;
}
```

nun wird bei der Hauptklasse über einen Backbuffer gezeichnet.
und ich Rufe in der paint funktion die draw funktion der anderen Klasse auf.

dabei wird die Variable offscreenGraphics übergeben und als Rückgabewert
entgegengenommen.

Nun gehe ich eigentlich davon aus, das das Bild im Backbuffer ist....
dies ist aber leider nicht der fall....
kann mir jemand sagen wie das funktionieren könnte????


----------



## André Uhres (22. Jan 2007)

```
/*
 * DrawingDemo.java
 */
package applet;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class DrawingDemo extends JApplet {
    private Image bild;
    private Graphics2D g2d;
    public void init(){
        setSize(400,300);
        add(new JPanel(){
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                if(bild == null){
                    bild = createImage(getWidth(), getHeight());
                    g2d = (Graphics2D)bild.getGraphics();
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setColor(Color.WHITE);
                    g2d.fillRect(0, 0, getWidth(), getHeight());
                    g2d.setColor(Color.black);
                }
                g2d.drawOval(10,10,100,50);
                g.drawImage(bild, 0, 0, bild.getWidth(this), bild.getHeight(this), this);
            }
        });
    }
}
```


----------



## ADVOAR1 (22. Jan 2007)

Was hat das denn jetzt schon wieder auf sich?????

Ich gehe jetzt davon aus, das dies die Klasse ist, die von der anderen Aufgerufen wird, aber logischerweise existiert jetzt das
paintComponent nicht wirklich....

Ich verstehe auch nicht so richtig was an meiner Version verhauen sein soll....

Wenn ich den Offscreen übergebe, da was reinschreibe und wieder
zurückgebe, muss doch da was drin stehen....


----------



## André Uhres (22. Jan 2007)

Müssen wir jetzt deinen Code erraten?


----------



## ADVOAR1 (22. Jan 2007)

hmm....

ok... hab eigentlich gedacht, ich hätte mich einigermaßen verständlich ausgedrückt....

ich bin dabei eine Klasse zu schreiben, bei welcher es um ein Menü geht.
dabei ist die Klasse an sich so aufgebaut:


```
public class CMenue
{
	//diese Klasse rödelt dann ordentlich rum, mit Bildern einfügen....
	//Dies geschieht, da ich einfachheitshalber so gemacht habe, das alle Menüpunkte und auch der Restliche Style
	//Aus bildern besteht.

	//So... und jetzt der Fehler....
	//Ich habe in dieser Klasse eine Funktion geschrieben, welche sich darum kümmern soll,
	//Alle Bilder auf den Bildschirm bzw. auf den Offscreen zu zeichnen.
	//Dafür habe ich die Funktion draw geschrieben.
	public Graphics draw(Graphics g)
	{
		g.drawImage(Bild1, x, y, width, height, this);
		//...
		g.drawImage(Bildx, x, y, width, height, this);
		//So... und jetzt soll die Funktion den veränderten Offscreen zurückgeben....
		return g;
	}
}
```

Jetzt kommt dann die Klasse, in welcher ich eine Instanz der anderen Klasse erzeuge.... quasi das Applet


```
public class CTest
{
	Graphics OffscreenGraphics;
	Image OffscreenImage;

	CMenue Menue;
	//Dann werden halt alle benötigten Menüpunkte e.t.c eingetragen...

	public void start()
	{
		OffscreenImage = createImage(800, 600);
		OffscreenGraphics = OffscreenImage.getGraphics();
	}
	
	//und dann soll das ganze Gezeichnet werden.
	public void paint(Graphics g)
	{
		//So und hier ist das Problem....
		//Eigentlich sollten meiner Meinung nach jetzt die gesamten Bilddaten
		//in dem Offscreen sein....
		OffscreenGraphics = Menue.draw(OffscreenGraphics);
		g.drawImage(OffscreenImage, 0, 0, this);
	}

	public void update(Graphics g)
	{
		paint(g);
	}
}
```


----------



## André Uhres (22. Jan 2007)

In dem Code ist kein Fehler erkennbar. Du musst schon ein KSKB machen.
<-- siehe "Lies mich" hier links nebendran.

EDIT: bitte Variablennamen immer mit kleinem Anfangsbuchstaben!


----------



## L-ectron-X (22. Jan 2007)

Kein Fehler kann man so nicht sagen, André.
Das Offscreen-Zeichnen ist doch gar nicht implementiert. Die update()-Methode ruft doch nur die paint()-Methode auf.
Hier wird doch gar nichts im Hintergrund gezeichnet und dann auf den Bildschirm kopiert.

@ADVOAR1: Benutz mal die Forumsuche, es gibt einige Codebeispiele zum Offscreen-Zeichnen bzw. Double Buffering.


----------



## André Uhres (22. Jan 2007)

L-ectron-X hat gesagt.:
			
		

> Kein Fehler kann man so nicht sagen, André.
> Das Offscreen-Zeichnen ist doch gar nicht implementiert. Die update()-Methode ruft doch nur die paint()-Methode auf.
> Hier wird doch gar nichts im Hintergrund gezeichnet und dann auf den Bildschirm kopiert..


Doch, ist alles da. Hab's sogar getestet  :wink:


----------



## L-ectron-X (22. Jan 2007)

Was hast du getestet? Deinen eigenen Code, oder den von ADVOAR1?
Wenn ADVOAR1 nämlich kein JApplet schreibt, wirds wohl so nicht gehen. Das Bild wird zwar gezeichnet werden, aber es wird flackern.


----------



## Guest (22. Jan 2007)

Und noch einmal.....

Hier die Datei CMenue.java:


```
import java.awt.*;
import java.applet.*;
import java.awt.image.*;

public class CMenue extends Applet
{
	Image Logo;
	
	public void CreateLogo(String LogoPic)
	{
		//Das Logo wird geladen...
		Logo = getToolkit().getImage(LogoPic);
	}
	
	public Graphics draw(Graphics g)
	{
		//Das Logo soll in den Offscreen, welcher übergeben wird gezeichnet werden...
		g.drawImage(Logo, 0, 0, Logo.getWidth(this), Logo.getHeight(this), this);
		//Der veränderte Offscreen soll nun wieder zurückgegeben werden...
		return g;
	}
}
```

Hier die Datei CTest.java:


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

public class CTest extends Applet
{
	Graphics offscreenGraphics;
	Image offscreenImage;
	
	CMenue Menu;
	
	public void start()
	{
		Menu = new CMenue();
		
		//der Offscreen wird erzeugt...
		offscreenImage = createImage(800, 600);
		offscreenGraphics = offscreenImage.getGraphics();
		
		//Hier wird das Logo in die Klasse geholt
		Menu.CreateLogo("Logo.JPG");
	}
	
	public void paint(Graphics g)
	{
		//Hier sollte jetzt eigentlich der Offscreen mit dem Logo zurückkommen...
		//Leider ist aber in dem Offscreen nichts drin..
		offscreenGraphics = Menu.draw(offscreenGraphics);
		
		//Wenn ich jedoch dies nehme funktioniert das ganze...
		//Image test = getToolkit().getImage("Logo.JPG");
		//offscreenGraphics.drawImage(test, 50, 50, test.getWidth(this), test.getHeight(this), this);
		
		//Es wird entgültig auf den Bildschirmgezeichnet, was sich im Offscreen befindet
		g.drawImage(offscreenImage, 0, 0, this);
	}
	
	public void update(Graphics g)
	{
		paint(g);
	}
}
```

und hier noch die Index.htm:


```
<html>
	<head>
		<title>Blubb</title>
	</head>
	<body>
		<applet code="CTest.class" width="800" height="600"></applet>
	</body>
</html>
```


----------



## ADVOAR1 (22. Jan 2007)

Nein...
da dürfte nichts flackern....

Hab ja im prinzip das ganze schon mal geschrieben....
nur halt ohne ne zweite Klasse....
also das Menü war direkt in dem Applet drin....
der Nachteil...
es wahr eine Monsterklasse und
sie kann nicht wo anders wieder verwendet werden....
Aber flackern tut da eigentlich nichts....


----------



## André Uhres (22. Jan 2007)

Nur zur Info,  hab's so getestet:

```
package applet;
/*
 * CTest.java
 */
import java.applet.*;
import java.awt.*;
public class CTest extends Applet{
    Graphics offscreenGraphics;
    Image offscreenImage;
    CMenue Menue;
    //Dann werden halt alle benötigten Menüpunkte e.t.c eingetragen...
    public void start() {
        Image bild = getImage(getCodeBase(), "1.gif");
        Menue = new CMenue(bild);
        offscreenImage = createImage(800, 600);
        offscreenGraphics = offscreenImage.getGraphics();
    }
    //und dann soll das ganze Gezeichnet werden.
    public void paint(Graphics g) {
        //So und hier ist das Problem....
        //Eigentlich sollten meiner Meinung nach jetzt die gesamten Bilddaten
        //in dem Offscreen sein....
        offscreenGraphics = Menue.draw(offscreenGraphics);
        g.drawImage(offscreenImage, 0, 0, this);
    }
    public void update(Graphics g) {
        paint(g);
    }
}
class CMenue extends Component{
    private int x, y, width, height;
    private MediaTracker mt;
    private Image bild1;
    //diese Klasse rödelt dann ordentlich rum, mit Bildern einfügen....
    //Dies geschieht, da ich einfachheitshalber so gemacht habe, das alle Menüpunkte und auch der Restliche Style
    //Aus bildern besteht.
    public CMenue(Image bild){
        mt = new MediaTracker(this);
        mt.addImage(bild, 0);
        try {
            mt.waitForAll();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        bild1 = bild;
        width = bild.getWidth(null);
        height = bild.getHeight(null);
    }
    //So... und jetzt der Fehler....
    //Ich habe in dieser Klasse eine Funktion geschrieben, welche sich darum kümmern soll,
    //Alle Bilder auf den Bildschirm bzw. auf den Offscreen zu zeichnen.
    //Dafür habe ich die Funktion draw geschrieben.
    public Graphics draw(Graphics g) {
        g.drawImage(bild1, 0,0,null); 
        //...
//        g.drawImage(Bildx, x, y, width, height, this);
        //So... und jetzt soll die Funktion den veränderten Offscreen zurückgeben....
        return g;
    }
}
```


----------



## André Uhres (22. Jan 2007)

Versuch mal das Bild so zu laden wie in meinem Beispiel 
und "CMenue" einfach von "Component" abzuleiten, statt von Applet.


----------



## ADVOAR1 (22. Jan 2007)

Alles klar...

so funzt das... aber mir ist noch nicht so klar warum....
soweit ich weiß ist dieses Objekt MediaTracker zum Überwachen da,
ob etwas fertig geladen ist...
aber wenn ich getImage nehme wirds doch geladen oder????

und ich meine so schlecht wird mein Computer doch nicht sein, das der mit dem Laden nicht aus dem Arsch kommt....


----------



## L-ectron-X (22. Jan 2007)

Das hat weniger mit deiner Kiste zu tun, sondern vielmehr mit der Verbindungsgeschwindigkeit zum Server.
Sollte der z.B. ausgelastet sein, wartet dein Applet so lange, bis alle Bilder da sind.


----------



## André Uhres (22. Jan 2007)

ADVOAR1 hat gesagt.:
			
		

> ..wenn ich getImage nehme wirds doch geladen oder?..


In einem Applet sollte man wohl die Methode "getImage" der Klasse "Applet" benutzen.
Diese Methode lädt das Bild nicht, sondern gibt einfach nur ein Image Object zurück.


----------



## ADVOAR1 (22. Jan 2007)

ja aber das geht über gar keinen Webserver e.t.c....

das ist lokal mit dem appletviewer gestartet....


----------



## André Uhres (22. Jan 2007)

Wenn's immer nur lokal genutzt wird, dann brauchst du auch kein Applet.


----------



## ADVOAR1 (22. Jan 2007)

Ich hab nicht gesagt, das es immer nur lokal genutzt wird, nur das es zur Zeit nur lokal genutzt wird....


----------



## André Uhres (22. Jan 2007)

Was willst du überhaupt? Es funktioniert problemlos und ist auf späteren Serverbetrieb eingestellt, ist doch alles super.


----------

