# JLabel verdeckt



## gollbat (27. Aug 2013)

Hallo zusammen,

ich habe folgendes Problem:

Ich programmiere zur Zeit ein kleines Minispiel. Das Spiel selber wird in einem Label angezeigt, bei dem die paint-Methode überschrieben ist. Das Label ist so gross wie das komplette Frame und hat einen schwarzen Hintergrund. 

Ich habe jetzt versucht noch ein zweites Label auf das Frame zu packen, in dem die Punktezahl eingetragen werden soll. Wenn ich nur dieses Label auf das Frame adde, wird es korrekt angezeigt. Wenn ich aber beide Label adde, wird nur das grosse Label angezeigt. Dabei ist es egal, welches der Label ich zuerst hinzufüge. 

Kann mir jemand helfen?

Viele Grüße,
gollbat


----------



## butterbemme (28. Aug 2013)

Lass doch erstmal den Code sehen, was du bisher gemacht hast.
Mit Layoutmanagern kennst du dich aus oder? Wenn nichg unbedingt anschauen. Mit diesen kannst du graphische Elemente anordnen, die müssen ja wissen wo sie hinsollen. Schätze es hat damit was zu tun


----------



## gollbat (28. Aug 2013)

Ich kenn mich ein bisschen mit Layout-Managern aus. Ich hab in meinem Frame allerding setLayout(null) gewählt und die Größe der Labels mit setBounds festgelegt.


----------



## butterbemme (28. Aug 2013)

Und nochmal: Poste deinen Code!
So ne Ferndiagnose, ohne zu sehen was du bisher gemacht hast, ist verdammt schwer.

Null-Layout so wie du es benutzt sollte man eigentlich nicht anwenden, da es unglaublich unflexibel ist (willst du 1 Element anders anordnen, musst du viele andere auch verschieben) und weil man leicht Fehler macht (Position + Bounds für alle Elemente von Hand angeben)


----------



## gollbat (28. Aug 2013)

```
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JLabel;


public class Label extends JLabel{
	
	Player p;
	Ball b;
	Computer c;
	
	public Label(Player p, int sizex, int sizey, Ball b, Computer c){
		this.p = p;
		setBounds(0, 0, sizex, sizey);
		setOpaque(true);
		setBackground(Color.black);
		this.b = b;
		this.c = c;
	}
	
	public void paint(Graphics g) {
		super.paint(g);
		g.setColor(Color.white);
		g.fillRect(p.x, (int) p.y, p.sizex, p.sizey);
		g.fillRect(c.x, (int) c.y, c.sizex, c.sizey); 
		g.setColor(Color.red);
		g.fillRect((int) b.x, (int)b.y, b.size, b.size);
	}
}
[/Java]

[Java]
import javax.swing.JFrame;
import javax.swing.JLabel;


public class Frame extends JFrame{
	
	JLabel l;

	public Frame(int sizex, int sizey, JLabel l){
		setSize(sizex, sizey);
		setTitle("PONG");
		setLayout(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setUndecorated(true);
		addKeyListener(new Keyhandler());
		setLocation(50, 212);
		this.l = l;
		add(l);
	}
}
[/Java]

[Java]
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;


public class main0r {
	
		static int sizex = 800;
		static int sizey = 600;
		
		
	public static void main(String[] args) {
		Player p = new Player(20, 100, 200, 10, 10f);
		Computer c = new Computer(20, 100, 200, sizex-10-20, 250-(100-50)/2);
		Ball b = new Ball(50, 100, -100, 250, 250, p, c);
		JLabel l = new Label(p, sizex, sizey, b, c);
		JLabel l2 = new JLabel();
		l2.setOpaque(false);
		l2.setBackground(Color.white);
		l2.setForeground(Color.white);
		l2.setBounds(100, 100, 100, 100);
		JFrame f = new Frame(sizex, sizey, l);
		f.add(l2);
		f.setVisible(true);
[/Java]
```


----------



## butterbemme (28. Aug 2013)

In einem schnell geschriebenen Beispiel bei mir funktioniert das was du vorhast in der Reihenfolge:
Erst Label im Vordergrund, dann Label im Hintergrund dem JFrame hinzufügen.

Bist du dir sicher dass du es auch in der Reihenfolge schon versucht hast? Dein oben geposteter Code machts genau andersherum

Dein Code ist nämlich ein ziemliches Wirrwarr und von einheitlicher Vorgehensweise sehe ich keine Spur.
Ein paar Hinweise:
- Du erstellst eigene Klassen "Frame" und "Label". Diese gibts schon in der Java API, das sint die awt-Versionen von JLabel und JFrame. Solch eine Namensgebung vermeiden
- Dein Frame erbt von JFrame, ist also auch ein solches. Bei swing-Komponenten wird nicht die paint-Methode überschrieben sondern paintComponent. Hier der Link zum Tutorial ausm Forum malen in swing
- Allgemein erbt man nur von einer Klasse, wenn man deren Verhalten ändern will. Die Sachen die du durch Vererbung erreichst könnte man ohne Probleme auch in einem Objekt von außen hervorrufen.


----------



## gollbat (28. Aug 2013)

Ja, ich bin mir sicher, dass ich beide Reihenfolgen probiert hab.

Ich hab nochmal ein neues Programm geschrieben, bei dem ich einfach 2 Labels auf ein Frame draufpacke und da funktioniert das komischerweise einwandfrei.

Wieso wird denn paintComponent und nicht paint überschrieben? Ich hab mal alles gleich gelassen und hab nur paintComponent statt paint in der Labelklasse geschrieben. Das funktioniert dann aber nicht richtig.


----------



## Goldfish (28. Aug 2013)

```
l2.setBackground(Color.white);
        l2.setForeground(Color.white);
```

glaubst du nicht, dass es vielleicht daran liegen könnte? Weiße Schriftfarbe auf weißem Hintergrund ist für das menschliche Auge nicht so gut zu sehen, wie ich mir denke ^^


----------



## butterbemme (28. Aug 2013)

gollbat hat gesagt.:


> Ja, ich bin mir sicher, dass ich beide Reihenfolgen probiert hab.
> 
> Ich hab nochmal ein neues Programm geschrieben, bei dem ich einfach 2 Labels auf ein Frame draufpacke und da funktioniert das komischerweise einwandfrei.



Versuche nun dein "neues" Programm Schritt für Schritt in Richtung deinem geposteten anzupassen. Irgendein Befehl sorgt für das veränderte Verhalten. Finde ihn

@Goldfish: Wenn der TO ein weißes Label auf ein schwarzes packt, das viel größer ist sollte das weiße sehr wohl vom menschlichen Auge zu erkennen sein


----------



## AcridMusak (28. Aug 2013)

Deine paint - Methode ist aber nicht überschrieben, wenn du es nicht ausdrücklich sagst
Annotation @Override.


----------



## gollbat (28. Aug 2013)

Hab nen @Override davor gestzt, es funktioniert aber trotzdem nicht.


----------



## Natac (28. Aug 2013)

AcridMusak hat gesagt.:


> Deine paint - Methode ist aber nicht überschrieben, wenn du es nicht ausdrücklich sagst
> Annotation @Override.


Das ist Schwachsinn. Die Annotation hilft nur dem Compiler dich auf mögliche Fehler beim Überschreiben hinzuweisen.

Prüfe den Rückgabewert, den Methodennamen (achte auf Groß- und Kleinschreibung) und die Übergabeparameter deiner Methode und der, die überschrieben werden soll. Die müssen alle identisch sein. Im Notfall einfach die Methode aus bspw. JLabel kopieren und in deiner Klasse einfügen.


----------



## Neumi5694 (5. Sep 2013)

AcridMusak hat gesagt.:


> Deine paint - Methode ist aber nicht überschrieben, wenn du es nicht ausdrücklich sagst
> Annotation @Override.


Das stimmt schon mal nicht, Annotations sind für die Programmausführung ohne Bedeutung.
Deshalb nennt man sie ja auch "Anmerkungen".

@butterBemme: Also in meiner Software funktioniert das Überschreiben von paint einwandfrei, zumindest bei JPanels.

Ich würde übrigens davon abraten, überhaupt Labels zu verwenden.
Verwende ein einzelnes Panel für dein Frame, in der Paint Methode lässt du dann die Texte mit drawText zeichnen.

Stelle in deiner Klasse 2 Methoden zum Setzen der Texte zur Verfügung, anstatt dann also

```
mylabel.setText("xyz")
```
zu schreiben, setzt du eine Variable in der Klasse und löst dann repaint aus.

Ein Spiel mit Lightwight Komponenten zu erstellen, ist eher kontraproduktiv.


ps: Ich kann meinen Vorrednern nur zustimmen, Label und Frame als Klassennamen solltest du wirklich nicht verwenden, die Lesbarkeit des Codes leidet darunter sehr (auch wenn es sich kompilieren lässt).


----------

