Java - Wie visuell-center eine bestimmte Zeichenfolge (nicht nur Schrift) in einem Rechteck
Ich versuche, visuell-center einen beliebigen Benutzer angegebene Zeichenfolge auf einem JPanel. Ich habe gelesen, Dutzende von anderen ähnlichen Fragen und Antworten hier SO, aber habe noch keine gefunden, die direkt-Adresse das problem, das ich habe.
Im code-Beispiel unten, getWidth() und getHeight() beziehen sich auf die Breite und Höhe des JPanel, auf dem ich lege den text-string. Ich habe festgestellt, dass TextLayout.getBounds() hat einen sehr guten job, mir zu sagen, die Größe von ein umschließendes Rechteck, welches den text. Also dachte ich, es wäre relativ einfach zentrieren Sie den text Rechteck, in das JPanel Rechteck durch die Berechnung der x-und y-Positionen auf dem JPanel der unteren linken Ecke des text-bounding-rectangle:
FontRenderContext context = g2d.getFontRenderContext();
messageTextFont = new Font("Arial", Font.BOLD, fontSize);
TextLayout txt = new TextLayout(messageText, messageTextFont, context);
Rectangle2D bounds = txt.getBounds();
xString = (int)((getWidth() - (int)bounds.getWidth()) / 2 );
yString = (int)((getHeight()/2) + (int)(bounds.getHeight()/2));
g2d.setFont(messageTextFont);
g2d.setColor(rxColor);
g2d.drawString(messageText, xString, yString);
Dies funktionierte perfekt für Saiten, die waren alle groß. Allerdings, wenn ich begann die Prüfung mit strings, die Kleinbuchstaben mit Unterlängen (g, p, y), der text war nicht mehr zentriert. Der absteiger auf die Kleinbuchstaben (die Teile, die sich unterhalb der Grundlinie der schriftart) waren gezogen zu niedrig gezielt auf das JPanel zu haben, der text erscheint zentriert werden.
Das ist, wenn ich entdeckt (Dank SO), dass der y-parameter übergeben drawString() gibt die baseline des gezeichneten text, nicht die Untergrenze. So, wieder mit der Hilfe von SO ich erkannte, dass ich brauchte, um passen Sie die Platzierung des Textes durch die Länge der Unterlängen in meinem string:
....
TextLayout txt = new TextLayout(messageText, messageTextFont, context);
Rectangle2D bounds = txt.getBounds();
int descent = (int)txt.getDescent();
xString = (int)((getWidth() - (int)bounds.getWidth()) / 2 );
yString = (int)((getHeight()/2) + (int)(bounds.getHeight()/2) - descent);
....
Getestet habe ich dies mit Streichern schwer in Kleinbuchstaben wie g, p, und y, und es hat Super geklappt! WooHoo! Aber....warten. Ugh. Wenn ich jetzt versuche mit nur Großbuchstaben, der text ist viel zu HOCH auf dem JPanel zu sehen zentriert.
Das ist, als ich entdeckte, dass TextLayout.getDescent() (und alle anderen getDescent () - Methoden, die ich gefunden habe, für andere Klassen) gibt den maximalen Abstieg von der FONT nicht von der spezifischen string. Also, mein groß-string angehoben wurde bis-Konto für den absteiger, der gar nicht auftreten, in dieser Zeichenfolge.
Was soll ich tun? Wenn ich nicht einstellen, dass die y-parameter für die drawString () - Rechnung für Unterlängen dann strings in Kleinbuchstaben mit Unterlängen sind optisch zu niedrig gezielt auf das JPanel. Wenn ich passen Sie die y-parameter für die drawString() unter Berücksichtigung der absteiger dann strings, die nicht enthalten alle Zeichen mit Unterlängen sind optisch zu hoch auf dem JPanel. Es scheint nicht zu irgendeiner Weise für mich, um zu bestimmen, wo die Grundlinie ist in der text-bounding-rectangle für einen GEGEBENEN string. Also, ich kann nicht herausfinden, was genau y zu passieren, um drawString().
Vielen Dank für jede Hilfe oder Anregungen.
- Wenn Sie nur beabsichtigen, um die Anzeige einer einzelnen Textzeile, Sie könnten mit etwas wie dieses Beispiel
- yString = (int)(((getHeight() + (int) bounds.getHeight()) / 2) - Abstieg);
Du musst angemeldet sein, um einen Kommentar abzugeben.
Während ich muck über mit
TextLayout
Sie konnte einfach dieGraphics
KontextFontMetrics
zum Beispiel...Okay, nach einigem Getue über...
Grundsätzlich, text-rendering erfolgt auf der Grundlinie, das macht die
y
position der Schranken erscheinen meist oberhalb dieser Stelle, so dass es wie der text ist lackiert, oberhalb dery
positionUm dies zu überwinden, müssen wir hinzufügen, die schriftart Aufstieg abzüglich der schriftart Abstieg zum
y
position...Zum Beispiel...
... Das ist, warum ich Liebe Rendern von text mit der hand ...
Runnable Beispiel...
Werfen Sie einen Blick auf Arbeiten mit Text-APIs weitere Informationen...
Aktualisiert
Wie bereits vorgeschlagen, könnte man eine
GlyphVector
...Jedes Wort (
Cat
undDog
) wird separat berechnet, zu zeigen, die UnterschiedeShape
erhalten Sie vonGlyphVector
. Auf diese Weise können wir nicht nur einfach um einen double-Wert von der Größe der Form, aber können es verwenden, wie ein Grafik-clip oder füllen Sie/es ziehen, wie man im dieses Beispiel. In Java scheint es ein Dutzend Möglichkeiten, um die Haut dieser Katze.TextLayout
ist wirklich "komisch" meiner Meinung nach, scheint eingängig, wenn im Vergleich zu anderen AnsätzenGlyphVector
haben Sie einen Blick auf das updateGlyphVector
.." war ich darauf warten, dass. 😉"A long time ago, in a galaxy, far, far away"
Sprechen, von denen Möge Der Frieden Mit Euch Sein,. 😉 Das war ein bisschen eine saga gelöst mit denGlyphVector
des Unicode-symbol für den Frieden unter den ein-Sterne-Warsesque schriftart. Die Schrift musste sich in einemArea
bevor ich konnte ordnungsgemäß tun, die Umrisse der verbundenen Buchstaben. Ich benutzte die Gliederung des peace-symbol alsClip
für die "Sterne-Bereich" das Bild. Es hat Spaß gemacht (auf einem Brötchen)!Ich denke diese Antwort ist der richtige Weg, es zu tun, aber ich habe in der Vergangenheit Probleme mit benutzerdefinierten Schriftarten und bekommen Ihre Grenzen. In einem Projekt musste ich zurückgreifen, die eigentlich immer den Umriss der Schrift, und mit diesen Grenzen. Diese Methode ist wahrscheinlich mehr Speicher-intensive jedoch scheint es sich um ein surefire Weg font Grenzen.
Wie ich schon sagte, bevor Sie versuchen, verwenden Sie die font-Metriken, aber wenn alles fehlschlägt, versuchen Sie diese Methode aus.
Shape
von der Glyphen. Sie können sehen, einige der Ergebnisse auf meine FaceBook-Seite.