repaint() Funktion erzeugt Flackern

12kukan

Mitglied
Hallo Community,

ich bin seit kurzem dabei ein Snakespiel zu programmieren. Nun bin ich auf ein Problem gestoßen...
Es geht um die repaint() Funktion, welche ich verwenden möchte, um mein Bild neu zu laden.
Immer wirklich immer, wenn ich das Spiel starte fängt es an zu flackern und es ist schwer möglich zu spielen.
Am besten poste ich einfach meinen Code.

[JAVA=134]
import javax.swing.*;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.logging.Level;
import java.util.logging.Logger;



public class Snake extends JFrame implements KeyListener, Runnable{

private static final long serialVersionUID = 1L;
private Dot dot = new Dot(3, this);
private boolean up, down, right, left;
private Apple apple = new Apple(this);

public Snake (String title) {
super(title);
this.setFocusable(true);
this.addKeyListener(this);
apple.createLocation();
}

public void paint(Graphics gr) {
super.paint(gr);
this.setFocusable(true);
this.addKeyListener(this);
//Malen Start

//Hintergrund
gr.drawImage(Toolkit.getDefaultToolkit().getImage("images/bg.png"), 0, 0, this);

//Dot malen
dot.paint(gr);

//Apfel erstellen
apple.paint(gr);

//Check für GameEnd
if (dot.getGameEnd()) {
gr.setFont(new Font("Arial", Font.BOLD, 25));
gr.drawString("Game Over!", 190, 220);
gr.setColor(Color.white);
gr.drawString("Punkte: " + dot.points, 200, 260);
}

}

public static void main(String[] args) {
//Main Logik
Snake snake = new Snake("Snake");
snake.setSize(500, 500);
new Thread(snake).start();
snake.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
snake.setUndecorated(true);
snake.setVisible(true);
snake.setLocation(700, 300);

}

@Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub

}

@Override
public void keyReleased(KeyEvent arg0) {
if (arg0.getKeyCode() == 37 && !right) {
left = true;
up = false;
right = false;
down = false;
}

else if (arg0.getKeyCode() == 38 && !down) {
up = true;
left = false;
right = false;
down = false;
}

else if (arg0.getKeyCode() == 39 && !left) {
right = true;
left = false;
up = false;
down = false;
}

else if (arg0.getKeyCode() == 40 && !up) {
down = true;
left = false;
up = false;
right = false;
}

}

@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub

}

@Override
public void run() {
while(true) {
//Check, für GameEnd
if (!dot.getGameEnd()) {

//Dot
if (up) {
dot.move("up");
}

else if (down) {
dot.move("down");
}

else if (left) {
dot.move("left");
}

else if (right) {
dot.move("right");
}


dot.checkApple(apple);
dot.checkCollision();

//Try, Catch
repaint(); {

}

}
try {
Thread.sleep(140);
} catch (InterruptedException ex) {
Logger.getLogger(Snake.class.getName()).log(Level.SEVERE, null, ex);
}

}

}


}
[/code]


Es gibt noch 2 auslagerungs Dateien, bei Bedarf, kann ich diese auch gern posten. Ich denke aber, dass die nicht nötig sein sollte!
 

12kukan

Mitglied
Ich dachte es wäre nötig, damit ich den Keylistener auch in anderen Klassen verwenden kann und damit ich meine Schlange allgemein bewegen kann...
Aber ich merke gerade, dass es überflüssig ist :D

Darf ich fragen, wie du darauf gekommen bist? xD
Und, ob dies mit der Problemlösung zusammenhängen könnte? :)
 

TheSorm

Bekanntes Mitglied
naja die methode repaint wird ja um die 68 mal aufgerufen pro secunde, das heist so oft wird auch ein key listener geaddet ?! ich denke das amcht das die performace einbricht ?!
 

12kukan

Mitglied
Stimmt, aber ich habe ihn bereits rausgenommen und es taucht das gleiche Problem auf...
Meinst du, dass ich das repaint zu zugemüllt haben könnte? :O
 

TheSorm

Bekanntes Mitglied
nimm mal das auch raus

Java:
this.setFocusable(true);

was steht da drin ?

Java:
       //Dot malen
        dot.paint(gr);
       
        //Apfel erstellen
        apple.paint(gr);
 
Zuletzt bearbeitet:

12kukan

Mitglied
Rausgenommen, selbe Sache, nichts passiert..

Apple.class:

Java:
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Toolkit;


public class Apple {
	
	private Component comp;
	private int x, y; 
	
	public Apple(Component comp) {
		this.comp = comp;
	}
	
	public void createLocation() {
		x = 10 * (int) (Math.random() * 49);
		y = 10 * (int) (Math.random() * 49);

 	}
	
	public int getX() {
		return x;
	}
	
	public int getY() {
		return y;
	}
	
	public void paint(Graphics gr) {
		gr.drawImage(Toolkit.getDefaultToolkit().getImage("images/Dot.png"), x, y, comp);	
	}

}



Dot.class:

Java:
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Toolkit;


public class Dot {
	
	private int dots;
	private int[] dotsX = new int[2500];
	private int[] dotsY = new int[2500];
	private Component comp;
	public boolean GameEnd;
	public int points = 0;
	
	public Dot(int dots, Component comp) {
	
		this.dots = dots;
		this.comp = comp;
		for(int i = 0; i < dots; i++) {
			dotsX[i] = 100 - 10 * i;
			dotsY[i] = 100;
		}
	}
	
	public void move(String position) {
		
		//Bewegung der gesamten Schlange
		for (int i = dots; i > 0; i--) {
			dotsX[i] = dotsX[(i - 1)];
			dotsY[i] = dotsY[(i - 1)];
		}
		
		
		//Bewegung
		if (position.equals("left")) {
			dotsX[0] -= 10;
		}
		
		else if (position.equals("right")) {
			dotsX[0] += 10;
		}
		
		else if (position.equals("up")) {
			dotsY[0] -= 10;
		}
		
		else if (position.equals("down")) {
			dotsY[0] += 10;
		}
	}
	
	public void checkApple(Apple apple) {
		if (dotsX[0] == apple.getX() && dotsY[0] == apple.getY()) {
			apple.createLocation();
			dots++;     //Auch += 2 möglich oder höher!
			points++;
		}
	}
	
	public void checkCollision() {
		//DotsX
		if (dotsX[0] <= 0) {
			GameEnd = true;
		}
		
		else if (dotsX[0] >= 500-10) {
			GameEnd = true;
		}
		
		//DotsY
		if (dotsY[0] <= 0) {
			GameEnd = true;
		}
		
		else if (dotsY[0] >= 500-10) {
			GameEnd = true;
		}
		
		for (int i = 1; i <= dots; i++) {
			if (dotsX[0] == dotsX[i] && dotsY[0] == dotsY[i]) {
				GameEnd = true;
			}
		}
	}
	
	public boolean getGameEnd() {
		return GameEnd;
	}
	
	public void paint(Graphics gr) {
	
		for(int i = 0; i < dots; i++) {
			gr.drawImage(Toolkit.getDefaultToolkit().getImage("images/Dot.png"), dotsX[i], dotsY[i], comp);			
		}
	}
}
 

TheSorm

Bekanntes Mitglied
2 dinge ersten: schreibe die paint anweisung direkt in die paint methode und nicht in die classe wie es jetzt ist;

zweitens: lade das Bild nur einmal im konstrukter der Klasse speicher das dann in einer varuiable ab und lasse das ausgeben ungefär so:

Java:
apple = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\apple.png"));

und dann eine getter methode für das image.

und dann schreibst du direkt ion die paint methode:

Java:
gr.drawImage(apple.getappleImage(), apple.getX(), apple.getY(), null );
 

12kukan

Mitglied
Ich muss das für apple und dot machen, oder?
Du hast jetzt nur Apple als Beispiel genommen.

Der erste Code steht soll ich mit der Funktion zum implementieren des Bildes austauschen, oder?

Und der zweite soll in die Paint-methode zum zeichnen der Bilder, richtig? :D

Danke bereits im Vorraus erstmal für die Geduld und Hilfe :)
 

TheSorm

Bekanntes Mitglied
genau nur das das Bild in dem Konstruktor der classe geladen wird sodass es nur einmal beim erstellen der classe geschiht :) und dan in einer "Image" variable speichern ;)
 
Zuletzt bearbeitet:

12kukan

Mitglied
Ich weiss nicht wie man eine Image Variable erstellt o_O
Das Prinzip habe ich verstanden :D
Ich bin mir nur in der Umsetztung unsicher :/ Ich krieg immer die Fehlermeldung,
apple cannot be resolved to a variable
. Daraufhin habe ich die Variable apple angelegt, aber das kann ja gar nicht gehen, weil du ja von einer Image Variable sprachst, diese kann ich nicht erzeugen, oder ich weiss nicht wie :/

Mein Programm will mir als Lösungsvorschlag diese Variable erzeugen:
Code:
private BufferedImage apple
Könnte das richtig sein?

Weil dadurch bekomme ich dann immer bei der Funktion zum Zeichnen des Bildes die Fehlermeldung,
The method getappleImage() is undefined for the type BufferedImage

Wenn er mir sagt, dass die Methode undefiniert ist, kann BufferedImage nicht richtig sein :/

Wie könnte ich hier vorgehen? :O

Vielen Dank nochmals! :)
 

TheSorm

Bekanntes Mitglied
Das ist ein Beispiel für die classe mit dem bild in der das image in einer variable mit getter gespeichert wirt.

Java:
package main;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class background {
	
	private Player player;
	
	private BufferedImage bgImage;
	private Rectangle bounding;
	
	private float bg_x;
	private float bg_y;
	private float f_dx;
	
	public background(Player player) {
		
		this.player = player;
		bg_x = 0;
		bg_y = 0;
		f_dx = 5;
		try {
			bgImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic\\background.png"));
			bounding = new Rectangle((int) bg_x, (int) bg_y,bgImage.getWidth(),bgImage.getHeight());
		} catch (IOException e) {e.printStackTrace();}
		
	}
	public void update() {
		if(bg_x <= -855) {
			bg_x = 0;
		}
		if(player.getBounding().x >= 400) {
			bg_x -= f_dx;
		}
		bounding.x = (int) bg_x;
		bounding.y = (int) bg_y; 
	}
	

	public BufferedImage getBgImage() {
		return bgImage;
	}

	public Rectangle getBounding() {
		return bounding;
	}
}

und das würde dann in der paint methode stehen:

Java:
gr.drawImage(bg.getBgImage(), bg.getBounding().x, bg.getBounding().y, null );
 
Zuletzt bearbeitet:

12kukan

Mitglied
Ich habe es genauso umgesetzt, wie in deinem Beispiel, mit Try | catch, doch es hat nicht geklappt... :(
In der Ausführung wurden die Bilder nicht mal mehr angezeigt :/
 

TheSorm

Bekanntes Mitglied
post dein code nochmal also von allen drei klassen!
oder wenn es welche giebt die fehler aus der konsole!
 
Zuletzt bearbeitet:

Sen-Mithrarin

Gesperrter Benutzer
du willst deinen "fehler" wissen warum dein "spiel" flackert ?

1) extends JFrame
2) implements KeyListener
3) implements Runnable
4) public void paint(Graphics) bei Swing


zu den einzelnen punkten

1) extends JFrame
man leitet grundsätzlich NICHT von JFrame (oder generell von einem top-level-container) ab, da man seine "funktion" nicht erweitert
WENN, dann nimmt man sich z.b. eine J/Panel und arbeitet damit

2) implements KeyListener
warum sollte deine ganze klasse denn ein öffentlicher KeyListener sein ? und vor allem dann noch wenn es ein top-level-container ist ?
neee .. sowas macht man nicht
wenn man einen listener für den internen gebraucht nimmt, dann arbeitet man wenn dann mit inneren klassen

@TheSorm
anmerkung : nur weil die klasse von JFrame erbt und KeyListener implementiert, hängt der listener noch lange nicht am JFrame dran
also muss man den JFrame "this" erstmal den Listener "this" dranhängen
auch wenns so in dieser konstellation ziemlich merkwürdig ist da zu diesem zeitpunkt das objekt weder als Listener noch als JFrame vollständig initialisiert ist, könnte zu nem StackOverflow führen

3) implements Runnable
joar, kann man als game-loop machen, aber wie auch bei Listener : jedes implements einer public klasse stellt diese als solche "öffentlich" zur verfügung, und sollte daher nur genau dann eingesetzt werden wenn dies auch genau so beabsichtigt ist
außerdem : while(true) ist genau so schreklich, vor allem wenn dann noch nicht mal mit if>break ne möglichkeit des "normalen" verlassens gegeben wird

4) public void paint(Graphics) bei Swing
WENN man schon mit GUI rumspielt, sollte man sich vorher auch genau damit befassen
und WENN man das tun würde, würde man auch wissen das man bei Swing NIE direkt paint(Graphics) überschreibt, sondern wenn dann immer nur paintComponent(Graphics)
zusätzlich : Swing bietet double-buffering an, das verhindert das flackern von alleine weil nicht direkt auf den screen gezeichnet wird sondern in den backbuffer der dann nur flipt
 

12kukan

Mitglied
Java:
	public void apple() {
		try {
			appleImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("images/dot.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void paint(Graphics gr) {
		gr.drawImage(getappleImage(), x, y, null );
	}
	
    public BufferedImage getappleImage() {
        return appleImage;
    }

Keine Fehlermeldung. Und das habe ich bis jetzt nur in Apple.java ausprobiert :)



@Sen:

Ich danke Dir für deine umfangreiche Kritik :)
Ich programmiere in Java erst seit sehr sehr kurzer Zeit und bitte daher, um dein Verständnis, dass ich einige Dinge missachtet habe :)

So wie ich das sehe sollte ich also das double-buffering verwenden, richtig?
Dies klingt mir am Plausibelsten :D
Nebebei eine Frage noch, all diese "Fehler", die du aufgezählt hast. Hänge diese mit dem Flackern zusammen, ich kann mir das nämlich nicht vorstellen :D
 
Zuletzt bearbeitet:

TheSorm

Bekanntes Mitglied
Du solst das im konstruktor machen nicht in einer Methode also das einlesen des Bildes ;)


@Sen-Mithrarin

Java:
public Snake (String title) {
        super(title);
        this.setFocusable(true);
        this.addKeyListener(this);
        apple.createLocation();
    }
 
    public void paint(Graphics gr) {
        super.paint(gr);
        this.setFocusable(true);
        this.addKeyListener(this);
        //Malen Start

ja das kla aber da macht er es erstens 2 mal und 2tens in einer in einer loop aufgerufenen methode?!
 
Zuletzt bearbeitet:

TheSorm

Bekanntes Mitglied
Java:
public void apple() {

ist nicht der Konstruktor!
der Konstruktor der classe Aplle.class wäre

Java:
public apple(){
}
 

12kukan

Mitglied
Java:
package Test;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Apple {
	
    try {
        appleImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("images/Dot.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
	
	private Component comp;
	private int x, y;
	private BufferedImage appleImage;
	
	public Apple(Component comp) {
		this.comp = comp;
	}
	
	public void createLocation() {
		x = 10 * (int) (Math.random() * 49);
		y = 10 * (int) (Math.random() * 49);

 	}
	
	public int getX() {
		return x;
	}
	
	public int getY() {
		return y;
	}
	
	public void paint(Graphics gr) {
		gr.drawImage(getappleImage(), x, y, comp);	
	}
	
	public BufferedImage getappleImage() {
        return appleImage;
    }

}

Entzwischen nicht mehr :D

Oh und das ist nen Error den ich bekommen hab, in der Konsole:

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Syntax error on token "{", { expected after this token
Syntax error, insert "}" to complete Block

at Test.Apple.<init>(Apple.java:11)
at Test.Snake.<init>(Snake.java:18)
at Test.Snake.main(Snake.java:52)
 
Zuletzt bearbeitet:

TheSorm

Bekanntes Mitglied
schreib mal das in deine repaint methode statt in der die paint methode von apple aufzurufen.

Java:
gr.drawImage(apple.getappleImage(), apple.getX(),apple.getY(), null );

oder

Java:
gr.drawImage(apple.getappleImage(), apple.getX(),apple.getY(), comp);
 
Zuletzt bearbeitet:

TheSorm

Bekanntes Mitglied
komm bsichen was must du auch selbst denken da ist ein Syntax error

Code:
Syntax error on token "{", { expected after this token
Syntax error, insert "}" to complete Block


du hast ergendwo geschweifte klammern vergessen zeigt dir dein schreib programm doch an ?!
 

12kukan

Mitglied
Ich denke schon mit^^
Ich habe, das auch untersucht, aber finde mal eine Stelle, wo dieser Fehler auftritt...
Es zeigt mir keinen Fehler mehr an, wenn ich das hier mache:

Java:
public class Apple {{
	
    try {
        appleImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("images/Dot.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }}

Aber das ist vollkommen absurd?!
 

TheSorm

Bekanntes Mitglied
IN DEN KONSTRUKTOR!

Java:
    package Test;
    import java.awt.Component;
    import java.awt.Graphics;
    import java.awt.Toolkit;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
     
    import javax.imageio.ImageIO;
     
     
    public class Apple {
       
             
        private Component comp;
        private int x, y;
        private BufferedImage appleImage;
       
        public Apple(Component comp) {
            this.comp = comp;
 try {
            appleImage = ImageIO.read(getClass().getClassLoader().getResourceAsStream("images/Dot.png"));
        } catch (IOException e) {e.printStackTrace();}
        }
       
        public void createLocation() {
            x = 10 * (int) (Math.random() * 49);
            y = 10 * (int) (Math.random() * 49);
     
        }
       
        public int getX() {
            return x;
        }
       
        public int getY() {
            return y;
        }
       
        public BufferedImage getappleImage() {
            return appleImage;
        }
     
    }
 
Zuletzt bearbeitet:

12kukan

Mitglied
Oh, entschuldige da muss ich mich vertan haben. :(
Ich habe es jetzt damit ausprobiert, der Apfel(Dot) ist aufgetaucht und es funzt alles einwandfrei^^
Aber das Bild flackert nach wie vor :/
 

Sen-Mithrarin

Gesperrter Benutzer
@TheSorm
ups, das er das in paint() drin hat hab ich ja mal total überlesen
liegt vielleicht daran das ich mir paint() nicht weiter angesehen habe da wie bereits erwähnt : unter swing einfach mal schlicht falsch !

@TO
in wie weit jetzt meine angemerkten punkte sich auf dein problem beziehen kann ich dir schlecht sagen, lediglich das du diese punkte so schnell wie möglich lernen solltest

zu punkt 4 allerdings : deine variante ist einfach falsch

Lesson: Performing Custom Painting (The Java™ Tutorials > Creating a GUI With JFC/Swing)

dort wird erklärt wie man in swing custom drawing umsetzt

grundsätzliche erklärung :

jedes GUI braucht einen sog. top-level-container der als schnittstelle zum OS dient auf dem dann "gezeichnet" werden kann
in swing sind dies grundsätzlich : JFrame, JDialog, JWindow oder JApplet
alle diese top-level-container enthalten nur eine direkte unter-komponente : JRootPane
JRootPane selbst ist von JComponent abgeleitet und dient damit, weil weiter von java.awt.Container erbend, einmal als container für alles was sonst noch mit "ins fenster" kommt, auf dr anderen seite aber als "unterste" rendering ebene

das ganze baut sich dann wie folgt auf

"ganz unten" als schnittstelle zum OS wie gesagt das JFrame
im JFrame kommt dann das JRootPane
im JRootPane kommt dann ein JLayeredPane
das JLayeredPane selbst wiederum hat zwei bereiche : einen bereich für eine eventuell vorhandene JMenuBar und einen bereich für das sog. ContentPane (normalerweise ein JPanel)
und ganz oben drauf, also noch über das ContentPane kommt dann das sog. GlassPane welches auf inputs von maus und tastatur reagiert

wenn man sich die DOC ansieht dann weis man : alles was man irgendwie mit dem JFrame macht wird, bis auf einige ausnahmen, komplett an das im RootPane liegende ContentPane delegiert

das ContentPane ist, wie schon gesagt, in der regel ein JPanel, aber auf jeden fall etwas was von java.awt.Container erbt


ergo : alles was gezeichnet wird, und das ist bei swing ja nun mal so bei allen komponenten, wird grundsätzlich auf das ContentPane gezeichnet

bevor wir nun also irgendwas selbst zeichnen müssen wir uns erstmal die "zeichenfläche" holen
das kann man entweder etwas länger über JFrame.getRootPane().getContentPane() machen, oder dank direkter delegation einfach JFrame.getContentPane() und erhält erstmal ein java.awt.Container objekt

um jetzt den regeln zu folgen und den compiler nicht zu verwirren prüfen wir erstmal ob das ContentPane eine instanz von JPanel ist

if(contentPane instanceof JPanel)

wenn ja, können wir dann direkt weiter arbeiten (wird in der regel immer so sein)
falls dies aber nicht der fall sein sollte erstellen wir ein neues JPanel und übergeben dies dem JFrame mit der methode setContentPane()

danach hat man erstmal grundsätzlich ein JPanel mit dem man dann weiter arbeiten kann


so ... und jetzt wieder in die DOC
JPanel erbt von JComponent
und da du bisher mit "public void paint(Graphics)" gearbeitet hast gucken wir doch mal was die DOC dazu sagt

"Applications should not invoke paint directly, but should instead use the repaint method to schedule the component for redrawing."
ok ... das sagt uns schon mal : wenn man etwas neu-zeichnen will callt man nicht selbst paint(Graphics) sondern ruft korrekterweise repaint() auf

"This method actually delegates the work of painting to three protected methods: paintComponent, paintBorder, and paintChildren. They're called in the order listed to ensure that children appear on top of component itself. Generally speaking, the component and its children should not paint in the insets area allocated to the border. Subclasses can just override this method, as always. A subclass that just wants to specialize the UI (look and feel) delegate's paint method should just override paintComponent."
ahh ... paint(Graphics) ist in Swing also speziell implementiert und eigentlich nur dafür zuständig in reihenfolge drei weitere methoden zu callen : paintComponent(Graphics), paintBorder(Graphics) und paintChildren(Graphics)
ergo : zumindest DAS sollte auch in eine überschriebene paint(Graphics) rein, was ja, laut DOC, durch aus erlaubt ist
der letzte satz ist aber interessant : auch wenn es hier eher um LaF geht und nicht weiter tragisch ist, so gibt es hier einen hinweis darauf das man besser nur paintComponent(Graphics) überschreiben soll
das ist vor allem dann wichtig wenn das JPanel weiterhin "funktionieren" soll


so ... und damit sind wir also an dem punkt wo man selbst zeichnen darf : paintComponent(Graphics)

was natürlich nicht fehlen darf : der super-call

und dann kommt man auch ganz logisch auf den punkt wie er im tutorial geschrieben ist

public void painComponent(Graphics)
{
super.paintComponent(Graphics);
//... custom painting
}


gut, man kann es natürlich auch genau so machen wie im tutorial und anstatt zu prüfen ob das ContentPane selbst ein JPanel ist zur sicherheit immer direkt selbst noch eins adden .. und sieht vielleicht auch etwas sauberer aus ... ich wollte lediglich auf die möglichkeit hinweisen



um also noch mal zurück zu kommen auf die frage : alles was du selbst zeichnen willst gehört in die paintComponent() des ContentPane ... oder in eine paintComponent() einer tieferen komponente
alles was darüber liegt bleibt dem system vorbehalten, es sei denn, wie gesagt, man weis wirklich genau was man tut


so ... und nach dem du jetzt bei paintComponent(Graphics) angekommen bist übernimmt Swing für dich den rest, nämlich z.b. das per default aktive double-buffering oder auch das korrekte zeichnen anderer komponenten

das einzige was ich abschließen noch mal erwähnen möchte : warum flackert es überhaupt ?
das liegt daran das du bei jedem repaint() das komplette fenster neu zeichnest, und da vor dem neu-zeichnen in der regel erstmal das löschen des alten inhaltes kommt bemerkt dies das menschliche auge als flackern, da kurz zwischen durch einmal alles weg ist und dann stück für stück neu erscheint

zusätzlich steht bei dir ein Thread.sleep(140) drin
und da das zeichnen zeit braucht und auch ein sleep meist länger ist kommst du grob gerechnet bei 1000 / 140 bzw 1000 / 150 auf irgendwas zwischen 6 2/3 und etwas mehr als 7 FPS

das menschliche auge braucht aber mindestens 25 FPS damit etwas als "flüssig" und "flackerfrei" empfunden wird

man könnte spaßeshalber mal ausprobieren was passiert wenn du statt 140ms nur 10ms wartest, dann kommst du auf theoretische ca. 100FPS, das sollte dann so schnell laufen das es nicht mehr flackert




ich hoffe ich konnte mit diesem etwas ausführlichen post etwas licht ins dunkle bringen
 

Sen-Mithrarin

Gesperrter Benutzer
ne lass mal ...
dafür isses nich gut genug geschrieben ... das haben andere sicher besser drauf
außerdem isses ja nu auch sehr problem-spezifisch und eher weniger für die allgemeinheit, wobei die erklärung sich halt die grundlage ist und eigentlich auch nur ne ausformulierte variante des java-tut ist (wo, muss ich erlich sagen, wenn mans nich weis, einiges so n bissl unter den tisch fällt)

außer wäre noch ne korrekte erklärung des double-buffering nötig ums als wirklich "komplett" darzustellen, und darauf hab echt keinen bock

trotzdem danke für die blumen =D
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Probleme mit der repaint-Funktion Java Basics - Anfänger-Themen 6
D Wenn ich repaint(); mache, flackert es so stark, das man fast nichts erkennen kann. Java Basics - Anfänger-Themen 11
S Repaint() Java Basics - Anfänger-Themen 1
J Erste Schritte Mit repaint() ist Label nicht sichtbar Java Basics - Anfänger-Themen 15
S Repaint() in der Schleife funktioniert nicht immer Java Basics - Anfänger-Themen 5
H Graphics / repaint Java Basics - Anfänger-Themen 8
D Verhindern das repaint beim vergrößern aufgerufen wird Java Basics - Anfänger-Themen 9
M Liste mit repaint aktualisieren Java Basics - Anfänger-Themen 1
E Probleme mit repaint() Java Basics - Anfänger-Themen 15
K Erkennt repaint nicht Java Basics - Anfänger-Themen 1
S KeyListener/ActionListener/paint()/repaint() Java Basics - Anfänger-Themen 3
I Anfängerfrage JPanel repaint() Java Basics - Anfänger-Themen 6
A externer repaint Aufruf Java Basics - Anfänger-Themen 9
G Problem mit repaint() Java Basics - Anfänger-Themen 2
J repaint() geht gar nicht; GUI aktualisieren Java Basics - Anfänger-Themen 10
J paint() vs repaint() Java Basics - Anfänger-Themen 3
C repaint wird nicht während Druck auf Maustaste ausgeführt. Java Basics - Anfänger-Themen 4
A Methoden repaint() zeichnet JPanel falsch Java Basics - Anfänger-Themen 3
P [JTable] Problem mit repaint() Java Basics - Anfänger-Themen 2
P Interpreter-Fehler Im for loop funkzioniert repaint nicht :( Java Basics - Anfänger-Themen 4
M repaint() in run-Methode funktioniert nicht Java Basics - Anfänger-Themen 9
W repaint() ruft paint() nicht auf Java Basics - Anfänger-Themen 9
J repaint() funktioniert nicht wie gewünscht Java Basics - Anfänger-Themen 30
I Hangman CardLayout/repaint? Java Basics - Anfänger-Themen 2
H Variablen Probleme mit repaint() Java Basics - Anfänger-Themen 2
Y im applet malen ohne repaint paint ? Java Basics - Anfänger-Themen 6
J repaint(); launisch ? Java Basics - Anfänger-Themen 3
E Altes Bild bei repaint() löschen? Java Basics - Anfänger-Themen 10
Z Wie repaint() bei Uhr realisieren? Java Basics - Anfänger-Themen 12
N JScrollPane repaint(); geht nicht Java Basics - Anfänger-Themen 4
I repaint bei jpanel Java Basics - Anfänger-Themen 10
T repaint wir nicht mehr geöffnet! Java Basics - Anfänger-Themen 38
T Canvas aktualisierung mit repaint Java Basics - Anfänger-Themen 5
C GUI aktualisieren: repaint, validate, Fenstergröße ändern bringt nichts Java Basics - Anfänger-Themen 13
Antoras Swing repaint und Nullpointer Java Basics - Anfänger-Themen 6
O repaint() wird nicht ausgeführt Java Basics - Anfänger-Themen 3
S problem mit repaint() in Thread Java Basics - Anfänger-Themen 6
Antoras swing und repaint-Ersatz Java Basics - Anfänger-Themen 8
G Automatischer repaint bei Swing so wie bei AWT? Java Basics - Anfänger-Themen 7
M Problem mit repaint Java Basics - Anfänger-Themen 2
R Probleme beim Repaint Java Basics - Anfänger-Themen 3
T repaint einer komponente Java Basics - Anfänger-Themen 2
E repaint() aufrufen Java Basics - Anfänger-Themen 12
F paintComponent mit repaint() aufrufen Java Basics - Anfänger-Themen 27
kulturfenster Probleme mit repaint() Java Basics - Anfänger-Themen 2
S SelectionListener + repaint().Verständnisproblem ;) Java Basics - Anfänger-Themen 7
K Repaint() in Methode Java Basics - Anfänger-Themen 13
G Frage zu repaint() Java Basics - Anfänger-Themen 5
D JPanel repaint() wird nicht gemacht! Java Basics - Anfänger-Themen 7
B Problem mit repaint() Java Basics - Anfänger-Themen 8
V Reihenfolge von Befehlen - hier repaint() zu spät Java Basics - Anfänger-Themen 13
G repaint in paint aufrufen? Java Basics - Anfänger-Themen 9
F repaint() - Methode verzögern lassen? Java Basics - Anfänger-Themen 3
I Erst repaint() dann zeichnen? Java Basics - Anfänger-Themen 6
D von paint() und repaint() im Applet Java Basics - Anfänger-Themen 4
J probleme mit repaint Java Basics - Anfänger-Themen 2
E Hilfe bei rekursiver Funktion Java Basics - Anfänger-Themen 3
FunkyPhil94 Wert in einer Lambda Funktion erhöhen Java Basics - Anfänger-Themen 3
M Eine Funktion zuweisen Java Basics - Anfänger-Themen 3
V Die Funktion des neuen Schlüsselworts in Java Java Basics - Anfänger-Themen 1
M variable in anderer funktion aufrufen Java Basics - Anfänger-Themen 10
_user_q Wie eine Methode/Funktion aus einer Klasse mit Constructor aufrufen? Java Basics - Anfänger-Themen 20
nelsonmandela Problem bei Ausgabe einer Switch - Case Funktion Java Basics - Anfänger-Themen 5
W GUI - JButton ohne Funktion? Java Basics - Anfänger-Themen 24
J Rekursive Funktion und return statement Java Basics - Anfänger-Themen 3
F Wie kann ich eine Funktion schreiben, die nur in bestimmten Fällen einen Wert zurückgibt? Java Basics - Anfänger-Themen 5
R Buttons ohne Funktion Java Basics - Anfänger-Themen 2
I Generische Funktion Java Basics - Anfänger-Themen 3
E Pervasive PSQL insert funktion geht nicht Java Basics - Anfänger-Themen 9
C Java Funktion: externe Daten vom Internet einbinden Java Basics - Anfänger-Themen 2
T Log Funktion erstellen Java Basics - Anfänger-Themen 1
M Wie kann ich eine Methode aus einem Interface in eine Klasse implementieren, so dass sie ihre Funktion ausführt? Java Basics - Anfänger-Themen 7
H Den Wert einer rekursiven Funktion bestimmen Java Basics - Anfänger-Themen 5
J In main() Datei geöffnet, von anderer Funktion beschreiben Java Basics - Anfänger-Themen 3
M toDouble Funktion Java Basics - Anfänger-Themen 3
Tino1993 Ellipse über draw Funktion ohne spur wandern lassen Java Basics - Anfänger-Themen 6
X Ackermannsche Funktion Java Basics - Anfänger-Themen 32
F Arrays: Mathematische Funktion Java Basics - Anfänger-Themen 19
P Dezimal zu Hexadezimalzahl Funktion Java Basics - Anfänger-Themen 5
S Verwenden von throw Exception an der Funktion Java Basics - Anfänger-Themen 2
M Arrays in Funktion Kopieren und Bearbeiten Java Basics - Anfänger-Themen 4
B Funktion mit mehreren Rückgabewerten aka Prozeduren? Java Basics - Anfänger-Themen 12
J Dynamisches Array durch split()-Funktion? Java Basics - Anfänger-Themen 3
D Funktion nur 1 Rueckgabewert Java Basics - Anfänger-Themen 9
M Wie lang eine Funktion/Methode? Java Basics - Anfänger-Themen 51
N den inhalt eines array per funktion ausgeben Java Basics - Anfänger-Themen 8
R Ackermann Funktion Java Basics - Anfänger-Themen 2
B Treetable (rekursive Funktion) aufbauen von Datenbank Java Basics - Anfänger-Themen 4
D Funktion zwei Arraylisten zu verleichen ob gleich funktioniert nicht Java Basics - Anfänger-Themen 26
N Abfragen eines Textes aus einem JTextField in Java, Funktion, CardLayout, Java Basics - Anfänger-Themen 2
T Rekursion Warum bricht meine Funktion nicht ab Java Basics - Anfänger-Themen 4
N Funktion funktioniert nicht immer Java Basics - Anfänger-Themen 6
E Contain-funktion überlisten Java Basics - Anfänger-Themen 4
J Division ohne Arithmetische Funktion Java Basics - Anfänger-Themen 2
S Funktion in Klasse auslagern Java Basics - Anfänger-Themen 4
J Problem mit Boolean bei Funktion! Java Basics - Anfänger-Themen 5
S Gibt es eine Funktion, die gewissermaßen eine Reihe von instanceOf() vereinheitlicht? Java Basics - Anfänger-Themen 19
D Nullstellen einer Funktion 3. Grades mit Horner Schema Java Basics - Anfänger-Themen 6
Aprendiendo Gibt es in der JAVA-API eine Funktion, die eine Dezimalzahl in eine binäre Zahl umwandelt? Java Basics - Anfänger-Themen 8
D Funktion gibt Dimension zurück Java Basics - Anfänger-Themen 11

Ähnliche Java Themen

Neue Themen


Oben