Panel Probleme (Tetris)

xyss

Aktives Mitglied
Moin,

Ich habe bei meinem aktuellen Projekt ein kleines Problem mit den Panels, es sollte ziemlich offensichtlich sein:

yf7lg8wd.png



Infos zum Problem:
Wenn man die Pausefunktion aktiviert (per Drücken der P-Taste), wird zusätzlich zum pausierten Spiel das Ganze noch visualisiert, indem das Spielfeld ausgegraut wird. Dies ist realisiert durch ein Panel, welches ich als pausePanel bezeichnet habe. Es ist die ganze Zeit vorhanden, jedoch nicht "sichtbar", da das Spielfeld-Panel dauerhaft repaintet wird. Bei aktivieren der Pause-Funktion wird einfach das pausePanel repainted damit es "drüber" liegt.
So, nun kommt es aber MANCHMAL dazu, dass dieser kleine Kasten, welcher ebenfalls durch ein eigenes Panel dargestellt wird, bei dem pausePanel mit erscheint, und ich bin absolut ratlos, woher das kommt, da diese beiden Panel rein gar nichts gemein haben... außer dass sie nunmal auf dem gleichen Frame liegen.

Genauere Erläuterung der Panels:

Java:
		add(pausePanel);
		add(scorePanel);
		add(gamePanel);
		add(ntPanel);
		add(bg);
		pack();

So werden sie zusammen auf das Frame gepackt.
Das pausePanel ist wie gesagt zuständig für das ausgegraute, sobald die Pause aktiviert wurde. Die Größe des Panels ist dementsprechend identisch mit der Spielfeldgröße.

Das scorePanel ist zuständig für die Labels (auch die Steuerung, daher sollte ich den Namen wohl demnächst ändern). Die Größe des score-Panels entspricht der weiß umrandeten Fläche an der rechten Seite (also ohne das Spielfeld)

Das gamePanel enthält das Spielfeld, und wird dementsprechend oft repainted. Die Größe entspricht exakt dem sichtbaren Spielfeld.

Das ntPanel ist das Panel, welches mir scheinbar die Probleme bereitet. Der Name steht für "NextTilePanel", da es sich hierbei um das kleine Kästchen handelt, in welchem angezeigt wird, welches Element als nächstes kommt. Es wird immer gleichzeitig mit dem gamePanel repainted.

Das bg Panel ist das background Panel. Es beinhaltet den schwarzen Hintergrund sowie die weißen Umrandungen etc.

Achja, und wenn es einmal vorgekommen ist, kann ich auch so oft ich will Pause drücken und wieder weg machen, es kommt immer wieder. Umgekehrt ebenso. Anders gesagt, entweder tritt es gar nicht auf, oder bei jedem Mal wo ich Pause drücke (bis ich das Programm halt beende)

Und ich frag mich nun einfach, wieso um alles in der Welt wird beim repaint() des pausePanels, das ntPanel oben links in die Ecke geklatscht...


So... falls es doch ein Code-basierter Fehler ist, und kein Denkfehler, werde ich noch Code posten..

lg
 
Zuletzt bearbeitet:

Bug Fisher

Bekanntes Mitglied
Hi xyss,

schick, wie du das gebaut hast; mein Tetris von vor paar Jahren war nicht so stylisch :)

xyss hat gesagt.:
So, nun kommt es aber MANCHMAL dazu...

'Manchmal' ist meistens ein Hinweis auf fehlende Synchronisation. Startest du eigene Threads (oder highleveligere Konstrukte, die Threads erzeugen) ?
Kannst du sicher sein, dass das repaint() immer und einzig vom EDT durchrannt wird ?

Auch möglich, dass du die EventQueue des EDT "bombardierst", dann kann es ebenfalls zu solchen Artefakten kommen.

Du nutzt vermutlich ein null-Layout ?? (setLayout(null))
Eine LayeredPane wäre auch eine Möglichkeit.

Rufe auf alle Komponenten, bei denen es Sinn macht, ein setOpaque(true).
 

xyss

Aktives Mitglied
Ich habe mir gedacht, dass ich bei Tetris keine extra Threads benötige, da im Endeffekt immer nur ein Element gleichzeitig in Bewegung ist.. Denkfehler? :eek:
Von daher -> nein ich starte keine eigenen Threads..

Ich hab mir auch schon gedacht, dass es ein Synchronisationsproblem ist, jedoch bin ich nunmal Ahnungslos, wie ich es löse :D

Das pausePanel benutzt ein BoxLayout, die anderen sind Null-Layouts (abgesehen vom ScorePanel benutze ich ja auch keine anderen Componenten, sondern "male" nur rum, dann brauch ich doch kein Layout, oder nicht?)

Das mit setOpaque werde ich mal versuchen :)

Etwas was mir auch aufgefallen ist:
Ich habe es jetzt so eingestellt, dass es ganz am Anfang pausiert ist, also, das gesamte Spiel wird initialisiert, aber bevor auch nur ein "tick" durchlaufen wird, wird auf Pause gesetzt. Und in dem Zeitpunkt, obwohl das ganze Frame ja bereits aufgebaut wurde etc, ist das ntPanel (NextTilePanel) nicht sichtbar.

Edit: Scheint doch kein Sync Problem zu sein.. ich konnte den Fehler "manuell" reproduzieren, in dem ich mehrmals das pausePanel und das ntPanel repainted habe..
Hier mal Schritt für Schritt, wie sich das Aussehen verändert, wenn ich die beiden Abwechselnd repainte, nachdem das ganze Frame fertig aufgebaut ist:

gbhaqvx4.png


fjbu5mjq.png


s8qukx7x.png
 
Zuletzt bearbeitet:

Bug Fisher

Bekanntes Mitglied
Zeig doch mal den ganzen Code um das
Java:
add(pausePanel);
add(scorePanel);
add(gamePanel);
add(ntPanel);
add(bg);
pack();
herum, wenn es dir nichts ausmacht.
 

xyss

Aktives Mitglied
Ich habe es vorerst so gelöst, dass ich bei der paint Methode vom pausePanel zuerst clearRect benutze. Dadurch sieht man während der Pause das Spielfeld nicht mehr, stattdessen ist das pausePanel komplett grau. Aber immerhin sieht man dadurch den Fehler auch nicht mehr. :p

backgroundPanel:

Java:
	public BackgroundPane(){
		setBounds(0,0,WIDTH,HEIGHT);
		setPreferredSize(new Dimension(WIDTH,HEIGHT));
		
	}

	public void paint(Graphics g){
		g.clearRect(0, 0, WIDTH, HEIGHT);
		
		/*Hintergrund*/
		g.setColor(Color.BLACK); 
		g.fillRect(0, 0, WIDTH, HEIGHT);
		
		
		//Spielfeldumrandung
		g.setColor(Color.WHITE);
		g.fillRect(GamePanel.OFFSET_X-5, GamePanel.OFFSET_Y-5, GamePanel.WIDTH+10, GamePanel.HEIGHT+10);
		g.setColor(new Color(0,102,255,170));
		g.fillRect(GamePanel.OFFSET_X-5, GamePanel.OFFSET_Y-5, GamePanel.WIDTH+10, GamePanel.HEIGHT+10);
		
		//Linke Box
		g.setColor(Color.WHITE);
		g.drawRect(GamePanel.OFFSET_X - 30, GamePanel.OFFSET_Y- 30, GamePanel.WIDTH + 60, GamePanel.HEIGHT + 60);
		
		
		int boxMidX = (GamePanel.WIDTH+60)/2;
		int boxMidY = (GamePanel.HEIGHT+60)/2;
		
		//Rechte Box
		g.drawRect(BOXCOOR_X, BOXCOOR_Y, RIGHT_BOX_WIDTH, GamePanel.HEIGHT + 60);
	
		
	}

GamePanel:
Java:
public GamePanel(Tetris tetris){
		this.tetris = tetris;
		setBounds(OFFSET_X,OFFSET_Y,WIDTH,HEIGHT);
		setPreferredSize(new Dimension(WIDTH,HEIGHT));
		setLayout(null);	
	}

	public void paint(Graphics g){
		g.clearRect(0, 0, WIDTH, HEIGHT);
		
		g.setColor(new Color(0,102,255,100)); //Blauer Hintergrund
		g.fillRect(0, 0, WIDTH, HEIGHT);
		
		g.setColor(new Color(0,0,0,100)); //SpielfeldRaster
		for (int i = 0; i <= Tetris.MAX_X; i++)
			g.drawLine(i*Tile.TILESIZE, 0, i*Tile.TILESIZE, HEIGHT);
		for (int i = 0; i <= Tetris.MAX_Y; i++)
			g.drawLine(0, i*Tile.TILESIZE, WIDTH, i*Tile.TILESIZE);
		
		
		tetris.getElement().paint(g); //Painte das aktuelle Element (das, welches gerade am runterfallen ist)
		
		Tile[][] t = tetris.getTiles(); //Sobald ein Element am Boden bzw an einem anderen Element ankommt, ist es ja nicht mehr steuerbar, sondern fest (bis auf Zeilenlöschungen), daher wird es dann in einen Tile[][] reingeschrieben. Ein "Tile" ist ein einzelnes Kästchen im Spielfeld. Ein Element (Spielstein) ist also aus 4 Tiles aufgebaut. Hier werden also die restlichen Tiles gemalt.

		for (int i = 0; i < t.length; i++){
			for (int j = 0; j < t[i].length ; j++){
				if (t[i][j] != null)
					t[i][j].paint(g);
			}
		}
		
	}

scorePanel
Java:
	public ScorePanel(Tetris tetris){
		score = 0;
		level = 1;
		lines = 0;
		this.tetris = tetris;
		
		//setBounds(BackgroundPane.BOXCOOR_X+1+10, BackgroundPane.BOXCOOR_Y + BackgroundPane.NEXTBOX_SIZE+ 30 + 20, WIDTH-10 , HEIGHT );
		//setPreferredSize(new Dimension(WIDTH,HEIGHT));
		setBounds(BackgroundPane.BOXCOOR_X+1, BackgroundPane.BOXCOOR_Y + 1, WIDTH, HEIGHT);
		setPreferredSize(new Dimension(WIDTH,HEIGHT));
		setBackground(Color.BLACK);
		setLayout(null);
		initLabels();
	}


pausePanel:
Java:
public PausePanel(){
		setBounds(OFFSET_X,OFFSET_Y,WIDTH,HEIGHT);
		setPreferredSize(new Dimension(WIDTH,HEIGHT));	
		setBackground(new Color(0,0,0,200));
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.state = STATE_PAUSED; //Es gibt auch noch STATE_GAMEOVER, das sorgt einfach dafür, dass je nach State ein anderer Text im Label steht, also entweder "Pause" oder "GameOver"
		
		lblMessage = new JLabel("Pause (P)");
		lblMessage.setFont(FONT);
		lblMessage.setForeground(COLOR);
		lblMessage.setAlignmentX(CENTER_ALIGNMENT);
		lblMessage.setBounds(10,87,100,40);
		
		add(Box.createRigidArea(new Dimension(10,HEIGHT/2-20)));
		add(lblMessage);
	}

	public void paint(Graphics g){
		g.clearRect(0, 0, WIDTH, HEIGHT); //Mit clearRect wird es "untransparent", wodurch der Fehler nicht mehr zu sehen ist, Notlösung.
		super.paint(g);
	}


nextTilePanel:
Java:
	public NextTilePanel(Tetris tetris){
		this.tetris = tetris;
		setBounds(BackgroundPane.BOXCOOR_X + 150, BackgroundPane.BOXCOOR_Y + 30, NEXTBOX_SIZE, NEXTBOX_SIZE );
		setPreferredSize(new Dimension(NEXTBOX_SIZE, NEXTBOX_SIZE));
	}
	
	public void paint(Graphics g){
		g.clearRect(0, 0, NEXTBOX_SIZE, NEXTBOX_SIZE); //cleare Alles
                g.setColor(Color.BLACK); 
		g.fillRect(1, 1, NEXTBOX_SIZE, NEXTBOX_SIZE); //schwarz füllen
		g.setColor(Color.WHITE);
		g.drawRect(0, 0, NEXTBOX_SIZE-1, NEXTBOX_SIZE-1); //Weiße Umrandung
		tetris.getNextPaint().paint(g); //Painte das nächste Element
	}
 

Bug Fisher

Bekanntes Mitglied
In Swing-Komponenten UNBEDINGT die
Java:
protected void paintComponent(Graphics)
nicht
Java:
public void paint(Graphics)
überschreiben.

Die Semantik ist exakt die gleiche, du brauchst also nur den Namen und die Sichtbarkeit zu ändern.

Und gewöhne dir besser an, die Annotation @Override zu verwenden, dann hilft dir auch der Compiler, falls du dich aus Versehen beim Methodennamen verschreibst.
 

Bug Fisher

Bekanntes Mitglied
Sorry, ich meinte mit Semantik das, was innerhalb der Methode steht. Vielleicht hätte ich besser Inhalt schreiben sollen.

Es ist einfach so: Swing (als Framework) ruft paint(Graphics g) auf, welches seinerseits paintBorder(g), paintComponent(g), paintChildren(g) auf den Plan ruft. (Ich hoffe die Reihenfolge ist richtig, das kann man nachlesen).
Wenn du jetzt paint() überschreibst, ohne dort super.paint() aufzurufen, machst du das ganze System kaputt und dadurch kann es eben zu solchen Effekten wie bei dir führen, da (relative) Layout-Informationen nicht korrekt weitergegeben werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P 2 Probleme mit Panel: index setzten und transparenz AWT, Swing, JavaFX & SWT 4
R Probleme bei einfügen einer JComboBox auf Panel AWT, Swing, JavaFX & SWT 4
F HILFE!!! Focus-Probleme bei unterschiedlichen Panel's AWT, Swing, JavaFX & SWT 3
L paintComponent in Panel eines Borderlayouts hinzufügen AWT, Swing, JavaFX & SWT 3
A Problem Spiel auf Panel der GUI zu bringen AWT, Swing, JavaFX & SWT 1
CptK Ordentlicher Code & Panel ab bestimmter Komponentenzahl scrollbar machen AWT, Swing, JavaFX & SWT 12
B JTextField in Panel positionieren AWT, Swing, JavaFX & SWT 1
R Swing Panel nur bei Maus sichtbar AWT, Swing, JavaFX & SWT 2
B mit Maus verschiebbares Panel AWT, Swing, JavaFX & SWT 2
S Labels in Panel erstellen AWT, Swing, JavaFX & SWT 1
H Aus Array Container Panel an Tabbedpane zuweisen AWT, Swing, JavaFX & SWT 29
S Swing Panel wird nicht neu gezeichnet AWT, Swing, JavaFX & SWT 3
O Kann kei neues Panel zum zeichnen aufrufen... AWT, Swing, JavaFX & SWT 4
J Overlay Panel statt neues Fenster AWT, Swing, JavaFX & SWT 6
CptK Swing DropdownMenu über Panel-Grenzen hinaus anzeigen AWT, Swing, JavaFX & SWT 1
J Aufklappbares Panel in Toolbar AWT, Swing, JavaFX & SWT 6
L ActionListener zu Button in Panel hinzufügen AWT, Swing, JavaFX & SWT 10
S Swing Panel übernimmt komponenten von anderem AWT, Swing, JavaFX & SWT 7
J Panel auf Frame positionieren AWT, Swing, JavaFX & SWT 9
J JFrame Panel hinzufügen AWT, Swing, JavaFX & SWT 10
B AWT Panel größe im BorderLayout einstellen AWT, Swing, JavaFX & SWT 1
K Swing Entfernen von Panel funktioniert nicht AWT, Swing, JavaFX & SWT 5
L JavaFX Animation für Panel wechsel AWT, Swing, JavaFX & SWT 3
L Swing JTable im Panel darstellen AWT, Swing, JavaFX & SWT 8
L JavaFX Klickverhalten bei einem Panel AWT, Swing, JavaFX & SWT 1
A Swing Panel mit ScrollBar AWT, Swing, JavaFX & SWT 7
K Panel verdeckt MenuItem AWT, Swing, JavaFX & SWT 5
H zwei gleich große Panels getrennt durch ein weiteres Panel AWT, Swing, JavaFX & SWT 10
N Swing Label auf Panel legen.. AWT, Swing, JavaFX & SWT 2
J Panel auf Frame löschen und neues Panel Hinzufügen AWT, Swing, JavaFX & SWT 4
T Swing Graphics auf Panel AWT, Swing, JavaFX & SWT 2
B Swing WindowBuilde: Menu -> anderes Panel wechseln AWT, Swing, JavaFX & SWT 1
U Java FX Zusätzliches Label per Knopfdruck während der Laufzeit auf Panel einfügen. AWT, Swing, JavaFX & SWT 2
P AWT Panel überschreibt vorheriges... AWT, Swing, JavaFX & SWT 2
Thallius Swing Warum kann man Texte im Panel nicht markieren? AWT, Swing, JavaFX & SWT 1
S NetBeans, Panel in Frame einfügen AWT, Swing, JavaFX & SWT 3
M AWT Panel wird nicht angezeigt AWT, Swing, JavaFX & SWT 7
P Fenstergröße ändern, Panel soll gleich bleiben AWT, Swing, JavaFX & SWT 2
M JavaFX Slide Panel AWT, Swing, JavaFX & SWT 2
P Swing Panel nicht sichtbar AWT, Swing, JavaFX & SWT 1
M Swing JtextField Panel in ander Panel aufrufen AWT, Swing, JavaFX & SWT 0
M Panel in geerbter JFrame Klasse adden AWT, Swing, JavaFX & SWT 4
S ScrollPane in Textarea und auf Panel AWT, Swing, JavaFX & SWT 4
D Swing Bei Button Click neues Panel laden AWT, Swing, JavaFX & SWT 3
D Panel wird nicht angezeigt und Fragen zum CardLayout AWT, Swing, JavaFX & SWT 6
S Swing JMenu löscht auf panel gezeichnetes AWT, Swing, JavaFX & SWT 3
X Java Panel zeitweise repainten AWT, Swing, JavaFX & SWT 8
W Swing Nicht-Editierbares Textfeld in Panel in ScrollPane AWT, Swing, JavaFX & SWT 9
B zweidimensionales Buttonarray auf Panel AWT, Swing, JavaFX & SWT 11
F JAVA-EDITOR: Panel in Frame aufnehmen AWT, Swing, JavaFX & SWT 3
F textarea lässt panel verschwinden AWT, Swing, JavaFX & SWT 4
T LayoutManager GridLayout panel.setSize funktioniert nicht AWT, Swing, JavaFX & SWT 1
A Panel lässt sich nicht bewegen AWT, Swing, JavaFX & SWT 2
E Panel mit Leben füllen AWT, Swing, JavaFX & SWT 2
K Swing Maus in Panel einsperren AWT, Swing, JavaFX & SWT 8
D Panel in Panel zentriert nicht richtig AWT, Swing, JavaFX & SWT 3
P Swing Panel-austausch über einen MenuListener AWT, Swing, JavaFX & SWT 2
1 Swing Bestimme ob ein Subelement eines panel den Fokus verloren hat AWT, Swing, JavaFX & SWT 2
P Swing Button über gesamtes Panel AWT, Swing, JavaFX & SWT 2
O LayoutManager Panel in Panel "maximieren" AWT, Swing, JavaFX & SWT 2
C AWT Horizontale Linie in einem Panel AWT, Swing, JavaFX & SWT 12
T Über mehrere Panel zeichnen AWT, Swing, JavaFX & SWT 2
B Export eines Panel mit ScrollBar AWT, Swing, JavaFX & SWT 4
S Größe von Panel verändern welches auf anderem Panel sitzt AWT, Swing, JavaFX & SWT 10
bluerob Panel im BorderLayout South wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
M Swing Panel klassenübergreifend ändern AWT, Swing, JavaFX & SWT 6
M Swing JFrame in einem Panel zeichnen AWT, Swing, JavaFX & SWT 3
A 2D-Grafik Panel inhalt löschen AWT, Swing, JavaFX & SWT 5
H Scroll Panel wird nicht hinzugefügt AWT, Swing, JavaFX & SWT 6
S Elemente im Panel in richtige Ausgangsstellung bringen AWT, Swing, JavaFX & SWT 10
X Swing Panel Extra Klasse & Aufruf über Button AWT, Swing, JavaFX & SWT 18
Kenan89 2D-Grafik paintComponent quetsch alles in Panel AWT, Swing, JavaFX & SWT 26
C Bild auf Panel vergrößern und verschieben AWT, Swing, JavaFX & SWT 4
C ImageIcon eines Labels auf einem Panel in neuem Fenster anzeigen AWT, Swing, JavaFX & SWT 2
H LayoutManager Panel verschieben sich AWT, Swing, JavaFX & SWT 5
O Swing JTree um Label (oder Panel) erweitern AWT, Swing, JavaFX & SWT 9
S Vaadin: Panel AWT, Swing, JavaFX & SWT 10
R paintComponent malt bei repaint() Rahmen um Panel AWT, Swing, JavaFX & SWT 7
C Etwas durchsichtig machen über einem Panel AWT, Swing, JavaFX & SWT 7
K Panel zu Laufzeit ändern AWT, Swing, JavaFX & SWT 6
T eigene Klasse für Panel AWT, Swing, JavaFX & SWT 9
D Panel aus externer Klasse holen AWT, Swing, JavaFX & SWT 2
L Swing dynamisches Image-Panel in Layout einbinden AWT, Swing, JavaFX & SWT 10
T Listener in anderen Panel deaktivieren AWT, Swing, JavaFX & SWT 3
H Verschiedene JPanels aus eigenen Klassen in JFrame einfügen, nur ein Panel sichtbar AWT, Swing, JavaFX & SWT 4
GUI-Programmer Informations-Panel an Label AWT, Swing, JavaFX & SWT 2
U Elemente im Panel zentrieren mit GridLayout AWT, Swing, JavaFX & SWT 3
J JPanel mit anderem Panel aus anderer Klasse setzen AWT, Swing, JavaFX & SWT 4
F 2D-Grafik Panel-Zeichnung erscheint nicht AWT, Swing, JavaFX & SWT 7
S Panel rapaint AWT, Swing, JavaFX & SWT 18
T AffineTransform wirkt sich nur auf dem ersten Panel aus AWT, Swing, JavaFX & SWT 3
K Swing: Panel in Panel erzeugen AWT, Swing, JavaFX & SWT 11
M Panel in SWT einfügen AWT, Swing, JavaFX & SWT 12
T auf Panel zeichnen AWT, Swing, JavaFX & SWT 4
A FormLayout Panel-Breite AWT, Swing, JavaFX & SWT 7
Dit_ "Expandable" Panel ? AWT, Swing, JavaFX & SWT 6
A Panel-Unterklasse funktioniert nicht AWT, Swing, JavaFX & SWT 16
A Panel zu klein AWT, Swing, JavaFX & SWT 14
M Eigenes Panel aus Component? AWT, Swing, JavaFX & SWT 5
S Swing Größe von JLabels verändern sich in einem Panel unterschiedlich AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben