Warum wird meine Graphik zwei Mal gezeichnet ?

Status
Nicht offen für weitere Antworten.

Kanitrino

Bekanntes Mitglied
Hallo Experten,

In dem unten gelisteten Programm (das ich hier auf's Wesentliche abgemagert habe) geht es darum, drei Graphiken in einem Frame zu vereinigen :

1. Eine Simulation "Brett" (Hasen, die Gras fressen)
2. Eine Graphik "Population", die die Anzahl der Hasen im Laufe der Zeit darstellt
3. und eine Benutzeroberfläche "Benutzer"

Alle drei Graphiken sind in je einer Klasse JPanel-Klasse enthalten.

Außerdem gibt es eine main-Klasse "Hasen" und einen "Manager".

Problem : Das "Brett" und die "Population" werden je zwei Mal gezeichnet, und zwar in die beiden Hälften des "Panels" mit GridLayout (2,1).

Kann mir jemand sagen, warum ?

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

public class Hasen extends JFrame
{
	Manager manager;
	Brett brett;
	Population pop;
	Benutzer gui;
	int msec	= 100;
	Panel panel;
	Container container;

	public Hasen()
	{
		this.setSize(1000, 650);
		brett	= new Brett();
		container = getContentPane();
		pop		= new Population();
		gui		= new Benutzer();
		manager = new Manager(brett, pop, msec);
		setBackground(Color.yellow);
		panel	 = new Panel();
		panel.setLayout(new GridLayout(2, 1));
		panel.add(brett);
		panel.add(pop);
		container.add("Center", panel);
		container.add("East", gui);

		manager.start();
	}

	public static void main(String[] args)
	{
			Hasen hasen 	= new Hasen();
			hasen.setVisible(true);
	}
}

class Manager implements Runnable
{
	Brett brett;
	Population pop;
	Thread running;
	int msec;

	public Manager (Brett brett, Population pop, int msec)
	{
		this.brett 	= brett;
		this.pop		= pop;
		this.msec	= msec;
	}

	public void start()
	{	if (running == null)
		{	running = new Thread (this);
			running.start();
	}	}

	public void run()
	{
		int i=0;
		while(i<4)
		{
			i++;
			brett.malen();
			pop.malen();
			verzoegerung (msec);
		}
	}

	public void verzoegerung (int msec)
	{
		try {Thread.sleep (msec);}
		catch(Exception e){}
	}
}

class Brett extends JPanel
{
	public void malen()
	{
		repaint();
	}

	public void paint(Graphics g)
	{
		g.setColor(Color.pink);
		g.fillRect(100, 100, 300, 200);
	}
}

class Population extends JPanel
{
	public void malen()
	{
			repaint();
	}

	public void paint(Graphics g)
	{
		g.setColor(Color.green);
		g.fillRect(0, 20, 500, 100);
	}
}

class Benutzer extends JPanel
{
	JSlider slider1;
	JButton bStart;
	JLabel label;

	public Benutzer()
	{
		setLayout(new GridLayout(0, 1));
		label = new JLabel("  Benutzeroberfläche");
		bStart 	= new JButton("S T A R T");
		slider1 = new JSlider(JSlider.HORIZONTAL, 0, 4, 1);
		add(label);
		add(slider1);
		add(bStart);
	}
}
 

Kanitrino

Bekanntes Mitglied
Ja schon, aber es ist ja eigentlich eine Animation (bzw. zwei). Ich wollte es euch nur nicht zumuten, den gesamten Klumpatsch lesen zu müssen und habe daher alles zu Rechtecken "abgemagert". Animationen lässt man eben mehrfach zeichnen.

Aber was meinst Du genau ? irgendwie wird natürlich alles doppelt gezeichnet, aber warum ? hat es was mit dem "Graphics g"-Objekt zu tun ?
 

André Uhres

Top Contributor
Was du "doppelt" siehst, sind einfach nur Unreinheiten weil der Hintergrund nicht gelöscht wird.
Statt paint musst du paintComponent benutzen, mit dem super Aufruf jeweils am Anfang:
Code:
   public void paintComponent(Graphics g) {
        super.paintComponent(g);
...
    }
 

Quaxli

Top Contributor
Ich hab' mal dran rumgefrickelt ;)

Folgende Änderungen habe ich eingebaut:

- den super-Aufruf in paint-Component. Wie André ja schon angemerkt hat, war das die grundsätzliche Ursache
- Manger erbt jetzt von Thread und implementiert nicht mehr Runnable, spart etwas Code ;)
- die malen-Methode habe ich aus Brett und Population rausgeworfen, da unnötig. Manager erhält jetzt ein Referenz
auf Hasen und macht einen repaint auf das komplette Fenster.


Was mir noch nicht ganz klar ist, ist der Sinn und Zweck des Codes, der in der run-Methode hinterlegt ist. Dieser Code ist nämlich sehr schnell abgearbeitet und dann wird keine repaint() mehr durchführt, so daß Veränderungen nicht mehr dargestellt werden, weil repaint() nicht mehr aufgerufen wird.


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

public class Hasen extends JFrame {

	private static final long serialVersionUID = 1L;

	Manager manager;
	Brett brett;
	Population pop;
	Benutzer gui;
	int msec = 100;
	Panel panel;

	Container container;

	public Hasen() {
		this.setSize(1000, 650);
		brett = new Brett();
		container = getContentPane();
		pop = new Population();
		gui = new Benutzer();
		manager = new Manager(brett, pop, msec, this);
		setBackground(Color.yellow);
		panel = new Panel();
		panel.setLayout(new GridLayout(2, 1));
		panel.add(brett);
		panel.add(pop);
		container.add("Center", panel);
		container.add("East", gui);

		manager.start();
	}

	public static void main(String[] args) {
		Hasen hasen = new Hasen();
		hasen.setVisible(true);
	}
}

class Manager extends Thread {
	Brett brett;
	Population pop;
	int msec;
	Hasen parent;

	public Manager(Brett brett, Population pop, int msec, Hasen parent) {
		this.brett = brett;
		this.pop = pop;
		this.msec = msec;
		this.parent = parent;
	}

	public void run() {
		int i = 0;
		while (i < 4) {
			//i++;       <<< 4 repaints und dann ist Schluß????
                       parent.repaint();
			verzoegerung(msec);
		}
	}

	public void verzoegerung(int msec) {
		try {
			Thread.sleep(msec);
		} catch (Exception e) {
		}
	}
}

class Brett extends JPanel {
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(Color.pink);
		g.fillRect(100, 100, 300, 200);
	}
}

class Population extends JPanel {

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(Color.green);
		g.fillRect(0, 20, 500, 100);
	}
}

class Benutzer extends JPanel {
	JSlider slider1;
	JButton bStart;
	JLabel label;

	public Benutzer() {
		setLayout(new GridLayout(0, 1));
		label = new JLabel("  Benutzeroberfläche");
		bStart = new JButton("S T A R T");
		slider1 = new JSlider(JSlider.HORIZONTAL, 0, 4, 1);
		add(label);
		add(slider1);
		add(bStart);
	}
}
 

Kanitrino

Bekanntes Mitglied
Hallo Quaxli,

Herzlichen Dank für Deine Antwort, ich werde es mir heute Abend genau angucken.

Der Grund für die kurze Schleife, die ja in der aktuellen Form eigentlich keinen Sinn hat, weil die Rechtecke nicht animiert sind : Ganz ohne Schleife trat das Problem nicht auf. Die Wiederholung an sich musste also Teil des Problems sein - was sich nun auch bestätigt hat.

Ich hätte da noch eine Zusatzfrage :
Eigentlich wäre die angemessene Darstellung für die zwei Animationen (= Rechtecke) ein BorderLayout, so dass die größere - pinke - Graphik ("Brett") den meisten Platz im "Center" einnimmt und die kleinere, grüne ("Population") darunter im "South". Wenn ich das aber so mache, drängt die größere die kleinere ganz aus dem Bild und lässt ihr nur noch einen viel zu schmalen Streifen übrig, obwohl sie garnicht den ganzen Platz bräuchte.

Wäre es nicht eigentlich die Aufgabe von BorderLayout, das besser zu organisieren ?
 

André Uhres

Top Contributor
Bei BorderLayout.SOUTH muss man in der preferredSize die Höhe angeben. Beispiel:
Code:
class Population extends JPanel {
    private Dimension size = new Dimension(0, 120);
    public Dimension getPreferredSize() {
        return size;
    }
 

Kanitrino

Bekanntes Mitglied
André,

Danke für den Tipp. Layout-Manager können ganz schön anstrengend sein !

Quaxli,

Deine Modifikationen sind insbesondere deshalb für mich unerwartet, da die paint-Methode nicht in den Klassen angesprochen wird. in denen sie steht, sondern in der main-Klasse, wo sie nicht steht, nämlich in (Hasen) parent. repaint();

Ist das den eleganter als umgekehrt ? Hat man denn so immer noch alles im Griff, wenn man mit mehreren Klassen mit je einer paint-Anweisung arbeitet ?
 

André Uhres

Top Contributor
Quaxli hat gesagt.:
Du sparst Dir jede Menge repaint-Aufrufe. Was soll daran also unelegant sein ? ;)
Die Erklärung scheint plausibel zu sein.
Allerdings, wenn man "intelligent malen" wollte, d.h. nur den Teilbereich, der sich verändert hat,
dann könnte es sich wieder anders verhalten. Denn mit "parent.repaint();" wird immer
der ganze JFrame mit all seinen Kindern neu gemalt, was u.U. nicht performant genug sein könnte.
 

Quaxli

Top Contributor
Was heißt "scheint plausibel"?

Ich behaupte, daß die meisten Anfänger kein Bedarf nach "intelligentem Malen" haben dürften. Zumal im ursprünglichen Programm auch nur die malen()-Methode hintereinander aufgerufen werden. Java ist durchaus mächtig genug, komplexere Zeichenmethoden ohne Probleme zu bewältigen. Und solange das ursprügliche Problem nicht darauf hinweist, daß der entsprechende Bedarf besteht (z. B. durch komplexe Berechnungen im Hintergrund), sollte man doch den Code so einfach wie möglich halten.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Meine Klasse wird nicht gefunden Java Basics - Anfänger-Themen 1
I Methoden Wieso wird mein Array "a" verändert und meine Variable "a" nicht? Java Basics - Anfänger-Themen 4
Zrebna Umgebungsvariable Wieso wird meine verwendete JDK-Version in der Prompt nicht erkannt? Java Basics - Anfänger-Themen 6
K Klassen Meine Klasse wird nicht anerkannt Java Basics - Anfänger-Themen 7
K Warum wird mir auf der Konsole des Servers nicht "xxxx" angezeigt (Server/Client) Java Basics - Anfänger-Themen 4
K Warum wird hier nur etwas in eine txt Datei geschrieben und nicht in alle drei (InputStream/OutputStream/Reader/Writer) Java Basics - Anfänger-Themen 1
I Exception wird gefangen, aber trotzdem in Error Log? Java Basics - Anfänger-Themen 10
H JDK installieren jdk-21 wird nicht erkannt Java Basics - Anfänger-Themen 13
T if-else Bedingung wird ignoriert Java Basics - Anfänger-Themen 4
K Warum wird mir "Empfangen vom Client:" nicht sofort ausgegeben(Server/Client) Java Basics - Anfänger-Themen 3
P Webseite vom Smartmeter wird nur unleserlich angezeigt Java Basics - Anfänger-Themen 7
A Warum wird mein jdk nicht gefunden? Java Basics - Anfänger-Themen 3
J jar Befehl wird nicht erkannt Java Basics - Anfänger-Themen 7
M Anonyme Klassen - Warum wird in der Konsole nichts ausgegeben? Java Basics - Anfänger-Themen 1
T catch(InputMismatchException) wird nicht ausgefürt/erkannt Java Basics - Anfänger-Themen 12
berserkerdq2 Intelij, wie kann ich einstellen, dass die aktuelle Klasse ausgeführt wird, wenn ich aufs Startsymbol drücke, gibts da eine Tastenkombination? Java Basics - Anfänger-Themen 11
M Verständnisfrage: Warum wird die Datei ohne Inhalt übertragen Java Basics - Anfänger-Themen 3
Ostkreuz Wieso wird die Methode nochmal aufgerufen? Java Basics - Anfänger-Themen 5
Oneixee5 Maven Plugin wird 2 mal ausgeführt Java Basics - Anfänger-Themen 10
R Compiler-Fehler Variable wird nicht gefunden bzw. erkannt? Java Basics - Anfänger-Themen 2
D Interface Methode wird ungewollt in der Subklasse überschrieben Java Basics - Anfänger-Themen 5
C Was tun wenn .class erwartet wird ? Java Basics - Anfänger-Themen 6
T Wie kann man es machen das ein Objekt nicht übermalt wird Java Basics - Anfänger-Themen 2
K Warum wird mir hier nach dem ersten Durchlauf zwei mal "welchen Datentyp wollen sie übergeben?" ausgegeben ? Java Basics - Anfänger-Themen 1
MiMa Ungültiges Datum wird nicht erkannt ?? Java Basics - Anfänger-Themen 6
schemil053 Multithread - Input verrutscht während etwas ausgegeben wird Java Basics - Anfänger-Themen 6
K REGEX - Rechnungsbetrag wird nicht richtig ausgelesen. Java Basics - Anfänger-Themen 3
_user_q Timer - ScheduledExecutorService wird schon vorher beendet Java Basics - Anfänger-Themen 5
X Erste Schritte Scanner eingabe wird übersprungen Java Basics - Anfänger-Themen 4
H Compiler-Fehler Klasse in einem Package wird nicht gefunden bzw. akzeptiert Java Basics - Anfänger-Themen 12
L Switch-Case Multiplikation wird nicht ausgegeben Java Basics - Anfänger-Themen 1
J In der Ausgabe wird ohne Eingabe in den else Block gesprungen. Java Basics - Anfänger-Themen 0
J In der Ausgabe wird ohne Eingabe in den else Block gesprungen. Java Basics - Anfänger-Themen 5
M Text wird in der Console nicht ausgegeben. Java Basics - Anfänger-Themen 11
S Datei anlegen Problem! Groß- und Kleinschreibung wird nicht unterschieden Java Basics - Anfänger-Themen 4
sserio Zweidimensionales Array [][] wird untereinander ausgegeben Java Basics - Anfänger-Themen 14
sserio Math. Befehl wird rot markiert Java Basics - Anfänger-Themen 5
M Rechteck wird nicht angezeigt Java Basics - Anfänger-Themen 3
B Bungeecord | ProxiedPlayer wird nicht in ArrayList hinzugefügt Java Basics - Anfänger-Themen 1
U Methode wird genutzt, ohne dass ich die aufrufe? Java Basics - Anfänger-Themen 4
S Methoden Return Rückgabewert wird nicht übergeben Java Basics - Anfänger-Themen 8
M Mein quellcode wird nicht in der Konsole ausgegeben Java Basics - Anfänger-Themen 3
I Code wird nicht ausgeführt Java Basics - Anfänger-Themen 2
M wird der Konstruktor nicht als 1. ausgeführt? Java Basics - Anfänger-Themen 13
G Main Methode wird beim ersten Aufruf nicht richtig ausgeführt Java Basics - Anfänger-Themen 1
K Präzedenregeln in Java sagen, dass +expr und -expr vor + von Addition und - von Addition stehen, warum wird dann z. B. a+b als eine Addition ausgeführ Java Basics - Anfänger-Themen 7
M Was wird hier genau getestet? Java Basics - Anfänger-Themen 9
M Wie schreibe ich eine if-Verzweigung um, so dass ein Bedingungsoperator benutzt wird? Java Basics - Anfänger-Themen 9
I Programm erkennt nicht an das Array zurückgegeben wird trotz Initialisierung *einfach* Java Basics - Anfänger-Themen 9
K Jlabel mit itemlistevent Text gegeben, wird nicht angezeigt Java Basics - Anfänger-Themen 5
P Mein Programm wird zwar erfolgreich Compiliert, öffnet sich aber nicht Java Basics - Anfänger-Themen 6
M Referenzen zuweisen und wird gleichzeitig ausgeführt Java Basics - Anfänger-Themen 6
O System.out.println wird nicht ausgegeben? Java Basics - Anfänger-Themen 11
el_pato DialogFenster wird nicht in Schleife geöffnet? Java Basics - Anfänger-Themen 30
J if-Schleife innerhalb einer if-Schleife wird in der Konsole nicht gelesen Java Basics - Anfänger-Themen 4
P Apache Derby wird in Eclipse trotz Anbindung nicht gefunden Java Basics - Anfänger-Themen 6
H Array wird als Rückgabewert nicht akzeptiert? Java Basics - Anfänger-Themen 2
Poppigescorn scan.nextInt() wiederholen bis eine Zahl eingeben wird Java Basics - Anfänger-Themen 7
F Session wird mehrfach erzeugt Java Basics - Anfänger-Themen 11
F Initialisieren eines Web-Mp3 Players in Tabs durch "booleans" erst wenn Tab geöffnet wird ...? Java Basics - Anfänger-Themen 1
fuerteb Compiler-Fehler Methode wird nicht bzw. als Fehler erkannt Java Basics - Anfänger-Themen 4
L JScrollPane wird nicht angezeigt Java Basics - Anfänger-Themen 10
D Hilfe beim Erzeugen eines Arrays NullPointerException wird ausgelöst Java Basics - Anfänger-Themen 11
J JTable Titel wird nicht angezeigt Java Basics - Anfänger-Themen 6
krgewb Long wird gerundet Java Basics - Anfänger-Themen 2
Zwanglos Warum wird nur die erste Zeile im while Block ausgeführt? Java Basics - Anfänger-Themen 8
F Wieso wird immer die falsche Mausposition angegeben? Java Basics - Anfänger-Themen 1
H GridPane wird nicht angezeigt Java Basics - Anfänger-Themen 0
M Was habe ich hier falsch, dass wenn ich z.B.: 11 eingebe mir false zurück gegeben wird? Java Basics - Anfänger-Themen 2
M Java Spiel wie Wer wird Millionär Java Basics - Anfänger-Themen 1
H Endkapital wird nicht korrekt ausgegeben. Java Basics - Anfänger-Themen 5
C Methodenrückgabe wird in der main nicht berücksichtigt Java Basics - Anfänger-Themen 2
X compareTo Methode wird ignoriert Java Basics - Anfänger-Themen 7
kodela Hauptklasse wird nicht gefunden Java Basics - Anfänger-Themen 3
H Befehl wird nicht ausgeführt - System.out.println Java Basics - Anfänger-Themen 3
I Input/Output Code wird doppelt ausgeführt Java Basics - Anfänger-Themen 3
P Bedingung in Schleife wird nicht ausgeführt Java Basics - Anfänger-Themen 5
P Variablen HttpResponse.getBody() wird automatisch org.json Object und kann nicht zu json.simple Object gecastet werden? Java Basics - Anfänger-Themen 7
N Selection Algorithmus: Methode wird nicht erkannt (BlueJ) Java Basics - Anfänger-Themen 3
N package wird doppelt im exporer angezeigt Java Basics - Anfänger-Themen 2
N Bedinugng If-Abfrage wird nie erfüllt Java Basics - Anfänger-Themen 4
M Else wird nicht ausgeführt. Java Basics - Anfänger-Themen 5
H Wie wird ein String intern gespeichert? Java Basics - Anfänger-Themen 10
A char array wird überschrieben Java Basics - Anfänger-Themen 6
E Methoden Action Event wird nicht vollständig ausgeführt Java Basics - Anfänger-Themen 3
L Iterieren durch eine ArrayList. Integer Array wird übergeben Java Basics - Anfänger-Themen 17
S setContentView(R.Layout.XXX) wird Rot angezeigt Java Basics - Anfänger-Themen 0
C Beispiel-Code mit Pair wird nicht compiliert. Java Basics - Anfänger-Themen 8
S Integer Wert wird nicht übernommen Java Basics - Anfänger-Themen 2
J Int wird als Null ausgegeben Java Basics - Anfänger-Themen 8
F Switch case wird als char nicht erkannt.... Java Basics - Anfänger-Themen 6
S for-Schleife wird ignoriert Java Basics - Anfänger-Themen 15
NeoLexx Variable für Array wird nicht korrekt übergeben Java Basics - Anfänger-Themen 45
tom.j85 Doppelte Foreach Schleife: Am Ende wird immer das Gleiche Objekt eingefügt Java Basics - Anfänger-Themen 4
M BorderLayout, 2Panels, EAST wird nicht angezeigt ?? Java Basics - Anfänger-Themen 2
K File wird in der .Jar nicht gefunden Java Basics - Anfänger-Themen 3
J String wird in GUI falsch ausgegeben Java Basics - Anfänger-Themen 10
J JDatePicker: Datum wird nicht in Textfeld übernommen Java Basics - Anfänger-Themen 5
G String wird nach Einlesen aus Datei nicht erkannt Java Basics - Anfänger-Themen 3
J bundel - Datei wird nicht gefunden. Trotz STRG-SHIFT-J Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben