JApplet und Zeichnen

J@ckWhiteIII

Mitglied
Hallo,
ich bin mal wieder bei einem JApplet zugange. Darauf möchte ich zeichnen.
ich weiß, dass man in einem "normalen" Applet einfach die paint(Graphics g) methode nehmen kann und update(Graphics g) überschreibt.
Nun sehe ich aber bei Eclipse mir STRG und Leertaste eine paint(), eine paintAll() und eine paintComponents() methode. Man beachte das "s" am Ende der Letzteren.

Wenn ich im JApplet einfach nur paint(Graphics g) aufrufe, flackert es (sollte dabei noch normal sein). Da ich aber auch die update(Graphics g) methode überschrieben habe, um so doppelt zu buffern, frage ich mich jedoch, warum dies nicht geht.
Eventuell kann da ja jemand helfen.
Hier erst einmal mein Code:

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

public class MainApplet extends JApplet implements Runnable {
	
	private static final long serialVersionUID = 1L;
	private Image image;
	private Graphics doubleG;
	private int p;
	
	public void init() {
		setSize(300,300);
		setFocusable(true);
		Thread t = new Thread(this);
		t.start();
	}
	
	public void start(){
		
	}
	
	public void stop(){
		
	}
	
	public void update(Graphics g) {
		if(image == null){
			image = createImage(this.getWidth(),this.getHeight());
			doubleG = image.getGraphics();
		}
		
		doubleG.setColor(getBackground());
		doubleG.fillRect(0, 0, this.getWidth(), this.getHeight());
		doubleG.setColor(getForeground());
		paint(doubleG);
		
		g.drawImage(image, 0, 0, this);
	}
	
	public void paint(Graphics g) {
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
		g.setColor(Color.RED);
		g.drawString("Dies ist ein Test", p, 40);
		
	}

	public void run() {
		while (true){
			p++;
			repaint();
			
			try {
				Thread.sleep(17);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

Achja, ich möchte kein JPanel verwenden, da ich gern irgendwelchen Komplikationen aus dem weg gehen möchte. Es wundert mich, dass in JApplet scheinbar keins eingebaut ist, obwohl in Applet ja ein Canvas ist...
 
Eigentlich braucht er diesen Tipp gar nicht. Denn in Swing sind alle GUI-Elemente bereits gepuffert. Man braucht also keinen Code für DoubleBuffering zu schreiben.

J@ckWhiteIII hat gesagt.:
Achja, ich möchte kein JPanel verwenden, da ich gern irgendwelchen Komplikationen aus dem weg gehen möchte.
Genau das ist hier nämlich der Vorwand, der dich sogar einen schwierigeren Weg suchen lässt. 😉
Wenn du etwas zeichnen möchtest, nimm bspw. ein JPanel und überschreibe die paintComponent()-Methode. Dort hinein kommt nicht das Laden der Bilder, nicht die Berechnung von Bildpositionen, kein repaint()-Aufruf etc. Nur dein Zeichencode.
Wenn du Bilder einbinden willst, kommt es auf die Komponente an, die sie anzeigen soll. Bei Komponenten wie JButton, JLabel etc. kannst du ein ImageIcon verwenden.
Hintergrundbilder kommen meist per paintComponent()-Methode auf ein JPanel.

Es kommt darauf an, was du erreichen möchtest.
 
Oh da hier von paint überschreiben und Canvas die Rede war habe ich gedacht er wills in AWT machen, aber stimmt ja, is ein JApplet. Dadurch überschreibst du gleich 2 Methoden von denen du die Finger lassen solltest.
 
Nun ja, das ist so: Ich hatte mir ein wundervolles Tutorial zum Thema Applets und Spiele angesehen. Da wurde IN der Applet klasse die paint() Methode überschrieben, so wie die update() Methode. Da das aber ja Alles AWT ist, fragte ich mich, ob ich dem ganzen nicht aus dem weg gehen kann, indem ich Ein JApplet nehme. Ein Applet hat ja etwas zum Zeichnen (in dem Falle ja scheinbar einen Canvas wegen paint()), da müsste ich also selbst das Flackern verhindern. Da ein JPanel ja aber eingebautes DoubleBuffering hat, dachte ich, dass ich in einem JApplet demnach eine paintComponent() Methode finden würde, für das (so dachte ich) JPanel des JApplets, welches gar nicht eingebaut werden müsse, da es schon in der JApplet Klasse vorhanden ist. Da ich kein paintComponent darin fand, war ich natürlich verwundert. ich persönlich hatte ja nur mit Swing gearbeitet und dachte mir "Na das ist ja toll, es gibt eine Swing variante des Applets. mal sehen, ob ich da nicht doppelt buffern muss!".
Und da in Applet ja scheinbar alles zum zeichnen inbegriffen ist, dachte ich, dass es bei JApplet genau so wäre. Dann hab ich mich ja scheinbar getäuscht.
 
Ein Programmierer, der in Swing seine GUIs schreibt, wird niemals direkt in einen JFrame oder JDialog zeichnen.
Das sind Toplevel-Container, in die z.B. JPanels eingefügt werden. JApplet ist auch ein Toplevel-Container. Ergo braucht dieser keine paintComponent()-Methode.
Das was du zeichnen möchtest, programmierst du in der paintComponent()-Methode eines JPanels oder einer JComponent.
 
Vielen Dank für deine Antwort; hat mich "aufgeklärt" über mein Verständnisproblem.
Allerdings muss ich dann doch noch etwas erfragen..und zwar wenn ich nun ein JPanel erstellt habe...Dann aber Daten über das JApplet (wie z.B. die Größe) brauche..sollte ich dann echt in der JPanel klasse getter und setter machen für diese Dinge? Denn eigentlich erschwert das (aus meiner derzeitigen Sicht) ja die ganze Sache. Zum Beispiel müsste das JPanel dann ja sämtliche anderen Klassen kennen und so weiter, bzw wenn ich eine andere Klasse habe, die eine draw() methode für sich hat, um z.B. ein kleines Bild anzuzeigen, müsste dann ja dem JPanel bekannt sein. Dann werden aber doch so ziemlich Alle Objekte in der JPanel Klasse sein, oder sehe ich das falsch?
Vielleicht ist das ja sogar so üblich, und ich weiß es nur nicht, aber das Ganze macht dann doch alles viel komplizierter? D:
 
Nee, eigentlich wird dadurch alles viel übersichtlicher. Der Code wird auf mehrere Klassen und Methoden verteilt, statt alles in eine Klasse zu quetschen und 100te von Zeilen einer einzigen Klasse im Blick behalten zu müssen. Das Ganze ist dadurch leichter zu warten und wiederverwendbarer.

Das Applet selbst kann seine eigene Größe auslesen und zum Auslesen durch weitere Klassen zur Verfügung stellen. Aber auch das im Applet sitzende Panel kann seine Größe abrufen und damit die des Applets, wenn es als Hauptpanel im Applet eingebettet wurde.
JApplets haben von Hause aus das BorderLayout (mehr dazu auch in der FAQ), können also eine oder mehrere Komponenten gleichzeitig aufnehmen.

Größere GUIs bestehen auch nicht aus nur einem Panel, sie sind sehr oft verschachtelt und nutzen geschickt die Fähigkeiten verschiedener LayoutManager.
Nur Anfänger benutzen das "NullLayout", weil sie meinen, dass das einfacher sei. Als ich angefangen habe, war ich der gleichen Meinung. :bloed: 😉

Und natürlich hat immer einer "den Hut auf". 😉
Bei Einem laufen immer alle Fäden zusammen - natürlich.
Ob es nun ein Haupt-Panel oder ein Controller ist. Nur so lassen sich vernünftig objektorientierte Programme schreiben.
 

Zurück
Oben