Kreis auf Label zeichnen ohne Schrift zu verdecken


HonniCilest

Erfahrenes Mitglied
Hallo,

ich glaube ich stehe irgendwie auf dem Schlauch ;-)

Ich möchte einen ausgefüllten Kreis auf ein Label um die Schrift herum zeichnen ohne dabei diese zu verdecken. Ich überschreibe hierfür die paintComponent-Methode. Das Ganze funktioniert super, solange ich den Kreis nur umrande und nicht ausfülle. Jedoch möchte ich genau dies tun und gleichzeitig weiterhin die setText-Methode des JLabels benutzen, also nicht die drawString-Methode in paintComponent.

Ich hoffe ich habe mich verständlich ausgedrückt ;-) Habt ihr einen Tipp für mich, wie ich das bewerkstelligen kann? Ich habe auch schon daran gedacht 2 Labels zu überlappen, aber damit bin ich auch nicht so glücklich ;-)

Danke wie immer im Voraus :)
 

Improof

Erfahrenes Mitglied
Hallo,

das liegt an der draw-Order. Das Label wird in deinem Fall vermutlich zuerst gezeichnet. Dadurch der Kreis auf dem Label -> Text wird verdeckt.

Ich würde jetzt sagen probier mal in der paintComponent Methode zuerst den Kreis zu zeichnen und danach super.paintComponent aufzurufen...aber dann wird wahrscheinlich dein Frame oder Panel den Kreis verdecken, weil dieser ja dann auch wieder vorher gezeichnet wird.

Gibt es einen Grund, warum du weiterhin mit der setText-Methode arbeiten willst?

Gruß
Daniel
 

Improof

Erfahrenes Mitglied
Hallo,

mir ist gerade noch ein (sehr unschöner) Lösungansatz eingefallen:

Du könntest ja dein Label auf die drawString-Methode "mappen". Das heißt, du übergibst der drawString-Methode die Koordinaten und den Text des Labels. Natürlich geht dann alles weitere, was dein Label so tolles kann verloren, aber du könntest weiterhin setText verwenden...aber das wäre wie gesagt nicht wirklich schön programmiert, tut halt einfach.

Gruß
Daniel
 

HonniCilest

Erfahrenes Mitglied
Ich würde jetzt sagen probier mal in der paintComponent Methode zuerst den Kreis zu zeichnen und danach super.paintComponent aufzurufen...aber dann wird wahrscheinlich dein Frame oder Panel den Kreis verdecken, weil dieser ja dann auch wieder vorher gezeichnet wird.
l
Danke, habe ich probiert, aber wie schon vermutet wird dann das andere überdeckt ;-)

Ich wollte weiterhin mit setText anstatt drawString arbeiten um mir den "mist" mit den Koordinaten zu ersparen. Der Text muss im Zentrum des Kreises sein. Ist der Text zu weit von der Mitte entfernt, so sieht das dann doof aus :) Das Label würde das zentrieren für mich übernehmen.
 

Improof

Erfahrenes Mitglied
Hallo,

jetzt verstehe ich das schon besser, an eine Zentrierung hab ich bisher noch gar nicht gedacht :D

Da wird dann aber der (wie gesagt...sehr unschöne) Workaround auch nichts. Du wirst nicht drum rum kommen das selbst zu lösen denk ich. Dafür brauchst du FontMetrics:

Der paintComponent-Methode wird ja ein Graphics-Objekt übergeben. Darauf dann .getFontMetrics() (evtl. mit der Font aufrufen, die du möchtest, falls nicht schon gesetzt) und kannst dir die Breite und Höhe in Pixeln von deinem String ermitteln. Über den Mittelpunkt von deinem Kreis kannst du dann die Koordinaten so ausrechnen, dass der String horizontal und vertikal im Kreis zentriert ist.

xString = xMiddle - (widthString / 2)
yString = yMiddle - (heightString / 2)

Und funktioniert dann natürlich immer, auch wenn du die Kreiskoordinaten mal änderst oder der Text sich verändert.

Wenn du's nun riiiichtig schön machen willst, dann bau dir eine eigene (ich denke mal Swing-) Komponente zusammen. Neue Klasse, erben von JComponent (kannst auch von JPanel erben, falls du Sub-Komponenten hinzufügen willst...brauchst du in deinem Fall aber nicht), einen String als Instanzvariable, da kannst dann wieder Getter und Setter machen wie bei deinem Laben (getText, setText) und was du sonst halt noch für Variablen brauchst und die paintComponent-Methode dann so überschreiben, dass wie oben erklärt, alles gezeichnet wird.
Falls du sowas dann öfter bräuchtest, kannst du ja einfach wie bei anderen Komponenten auch eine neue Instanz erzeugen, auf dein Panel hinzufügen und gezeichnet wird ja dann alles von selbst :)

Gruß
Daniel