AWT FontMetrics height

N

Nestos

Gast
Guten Morgen.

Ich versuche jetzt schon seit mehreren Tagen dieses Problem zu lösen, bin aber bis jetzt noch auf keinen Lösungsweg gekommen.

Wie der Titel schon sagt [SlaterB: geändert], versuche ich ein Polygon in Form eines Pfeiles neben einem String vertikal zu zentrieren, sodass der Pfeil genau in der Mitte des Textes ist.

Java:
				int stringHeight = (int) (g.getFontMetrics().getStringBounds(menuItems[i].getText(), g).getHeight() - g.getFontMetrics().getDescent() - g
						.getFontMetrics().getLeading()) / 2;
				
				//int stringHeight = ((int) g.getFontMetrics().getAscent()) / 2;
				
				//int stringHeight = menuItems[i].getFont().getSize() / 2;
				
				//int stringHeight = g.getFontMetrics().getAscent() / 2;
				
				System.out.println(stringHeight);
				
				int[] arrow_x = { width / 2 - 70, width / 2 - 60, width / 2 - 70 };
				int[] arrow_y = { menuItems[selected].getY() - stringHeight - 10, menuItems[selected].getY() - stringHeight,
						menuItems[selected].getY() - stringHeight + 10 };
				Polygon arrow = new Polygon(arrow_x, arrow_y, 3);
				g.fillPolygon(arrow);

So habe ich es probiert, bekam aber nicht das gewünschte Ergebnis.

Das ganze Projekt:
SimpleMenuTest

Ich hoffe ihr könnt mir helfen.

MfG,
Nestos.
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
kaum jemand möchte wohl ein ganzes Zip downloaden, was spricht dagegen eine 100-Zeilen Test-GUI zusammenzustellen?
du könntest auch noch selber testen und Ergebnisse/ Screenshots dazu posten,

male manuell waagerechte Linien, einfach malen, schauen, korrigieren,
finde das unteren und obere Ende des Textes ungefähr heraus, wie groß ist der vertikale Abstand in Pixeln, stimmt stringHeight in etwa?
wo genau liegt in einem Beispiel die Hälfte davon?
vergleiche das mit deinen berechneten Koordinaten, width / 2 - 70 usw.,

wo landet dieser Pfeil im Bild aktuell, was ist eigentlich die Frage? ist er gar nicht zu sehen, weit entfernt vom Text,
geht es um 1-2 Pixel Abweichung?
bist du überhaupt geübt im Umgang mit Polygon (erübrigt sich wenn der Pfeil irgendwo zu sehen ist)

du siehst:
tausende Informationen und Vorgänge könnten von deiner Seite kommen, nicht nur die Aufgabe weiterreichen ;)

-----

[c]menuItems[selected].getY() - stringHeight[/c] hast du übrigens 3x hintereinander stehen,
für sowas unbedingt Variablen einfügen
[c]int baseYPfeil = menuItems[selected].getY() - stringHeight[/c]
 
Zuletzt bearbeitet von einem Moderator:
N

Nestos

Gast
kaum jemand möchte wohl ein ganzes Zip downloaden, was spricht dagegen eine 100-Zeilen Test-GUI zusammenzustellen?
du könntest auch noch selber testen und Ergebnisse/ Screenshots dazu posten,
Ich stand unter Zeitdruch, ich reiche es aber jetzt nach. ;)

male manuell waagerechte Linien, einfach malen, schauen, korrigieren,
Das habe ich bereits gemacht, kam dadurch aber trotzdem nicht auf den richtigen Wert.

finde das unteren und obere Ende des Textes ungefähr heraus, wie groß ist der vertikale Abstand in Pixeln, stimmt stringHeight in etwa?
Genau hier liegt das Problem: Ich finde einfach nicht diese Kanten.
Ich hab wirklich viel probiert, kam aber nach längerer Zeit (4 Stunden, mit suchen) nicht auf ein brauchbares Ergebnis, da man die Font ja auch ändern kann und somit die Werte nicht konstant sind.

wo landet dieser Pfeil im Bild aktuell, was ist eigentlich die Frage? ist er gar nicht zu sehen, weit entfernt vom Text,
geht es um 1-2 Pixel Abweichung?
Er landet in ungefähr neben dem Text, es handelt sich aber immer um Abweichungen von >= 10 Px, ja größer die Font, desto größer die Abweichung.

bist du überhaupt geübt im Umgang mit Polygon (erübrigt sich wenn der Pfeil irgendwo zu sehen ist)
Zwar nicht in Java, aber ich habe öfters damit in anderen Sprachen gearbeitet. Und aus dem obrigen zu schließen sieht man den Pfeil.

Java:
menuItems[selected].getY() - stringHeight
hast du übrigens 3x hintereinander stehen,
für sowas unbedingt Variablen einfügen
Java:
int baseYPfeil = menuItems[selected].getY() - stringHeight
Ich hab es nur zum Testen schnell hingeklatscht. Optimieren kann man es nachher immer noch. :D

Hier zwei Beispiele:
Font-Größe: 30
Hier sieht man es noch nicht so gut, aber man bemerkt eine Abweichung:
Debug1.png


Font-Größe: 60
Hier sieht man es schon sehr gut:
Debug2.png


Hier die Frage etwas genauer gestellt:
Ich versuche den vertikalen Mittelpunkt eines gezeichneten Strings zu finden.
Mir fehlt es einfach an Erfahrung mit AWT, aber die versuche ich eben zu erlangen. ;)

Probiert habe ich es mit allen möglichen Mothoden der Klassen Font und Graphics.

MfG,
Nestos.
 
N

Nestos

Gast
Hier noch ein Testskript:

Java:
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.*;

public class test extends JPanel implements Runnable
{
	private static final long	serialVersionUID	= 1L;
	private static String		title				= "Debug";
	private static Dimension	cords				= new Dimension(400, 300);
	
	public static boolean		running				= true;
	
	public static void main(String[] args)
	{
		new test();
		
	}
	
	public test()
	{
		JFrame frame = new JFrame(title);
		frame.setResizable(false);
		frame.add(this);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setSize(cords.width + frame.getInsets().right + frame.getInsets().left, cords.height + frame.getInsets().bottom + frame.getInsets().top);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	
	@Override
	public void run()
	{
		while (running)
		{
			repaint();
			
			try
			{
				Thread.sleep(10);
			}
			catch (InterruptedException e)
			{
			}
		}
		System.exit(0);
	}
	
	@Override
	public void paintComponent(Graphics g)
	{
		int stringHeight;
		
		super.paintComponents(g);
		
		g.setColor(Color.green);
		g.fillRect(0, 0, cords.width, cords.height);
		
		g.setColor(Color.black);
		g.drawRect(0, 0, cords.width - 1, cords.height - 1);
		
		g.setColor(Color.black);
		g.setFont(new Font("Monospaced", 0, 70));
		
		g.drawString("Test", 100, 100);
		
		stringHeight = (int) (g.getFontMetrics().getStringBounds("Test", g).getHeight());
		
		g.drawLine(80, 100, 80, 100 - stringHeight);
		g.drawLine(90, 100, 90, 100 - stringHeight / 2);
		
		
		g.drawString("Test", 100, 200);
		
		stringHeight = (int) (g.getFontMetrics().getAscent());
		
		g.drawLine(80, 200, 80, 200 - stringHeight);
		g.drawLine(90, 200, 90, 200 - stringHeight / 2);
	}
	
}
 
S

SlaterB

Gast
sieht in der Tat nicht allzu gut aus,
habe noch paar Internet-Links mit Beispielen angeschaut, so schöne Linien wie in den Tutorials,
etwa
kleinfontMetrics.gif

konnte ich nicht reproduzieren,
mache Programme behaupten da mehr oder weniger was sinnvolles zu tun, etwa
Font base line : Font Metrics2D GraphicsJava Tutorial
allerdings ohne Bild daneben letztlich auch nicht konsequent

nach einer Weile dann ein Thema welches auch nicht so zufrieden ist:
Java: FontMetrics ascent incorrect? - Stack Overflow

mein Fazit: scheint (im Moment) nicht gut zu funktionieren,
gehe notfalls davon aus, dass die Höhe einfach zu hoch ist und finde dir selber einen Faktor, z.b. 70%, der von den gegebenen Zahlen herunterrechnet,

getStringBounds() scheint sich bei mir nicht mal groß am Text zu orientieren, zu "a" liefert es dieselbe Höhe wie zu "TgöÖÈj"..,
nur die Breite wird angepasst,
wenn das komplett nicht funktioniert, kann man eigentlich gleich von der Font-Size 70 aus rechnen..

edit: habe den Titel geändert, auf das Problem konzentriert
 
Zuletzt bearbeitet von einem Moderator:

bERt0r

Top Contributor
Mit einem der mächtigeren Layoutmanager kriegt man sowas ohne Probleme und Rechenquälerei hin. Pack deine Strings und deinen Pfeil in Labels (Icon) ordne sie vertikal zentriert an.
In etwa das gleiche:
 

Ähnliche Java Themen


Oben