Java: a friendlier way to get an instance of FontMetrics

Is there a more convenient way to get an instance of FontMetrics than

FontMetrics fm = Graphics.getFontMetrics(Font); 

I hate this way because of the following example:

If you want to create a menu in the game and want all the menu items in the center of the screen to need fonts. But mainly menu items can be clicked. So I create an array of Rectangles , and all the rectangles fit the elements, so when the mouse is pressed, I can just use

 for (int i = 0; i < rects.length; i++) if (rects[i].contains(mouseX, mouseY)) { ... } 

But to create rectangles, I also need FontMetrics for their coordinates. Therefore, this means that I have to build all my rectangles in the paint method of my menu.

So, I want to get FontMetrics so that I can build Rectangles in a method called by the constructor.

+4
source share
6 answers

The really correct answer is to use Toolkit.

 Font font = new Font("Courier New", Font.PLAIN, 14); FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font); 
+5
source

For me the easiest way:

 Font font = new Font("Helvetica",Font.PLAIN,12); Canvas c = new Canvas(); FontMetrics fm = c.getFontMetrics(font); 

Benefits:

  • If you call c.getGraphics (), it will return null (while there is no graphic object)
  • This (canvas) will also work in headless mode.

Now you can easily get height and width ...

+10
source

As soon as the background component i.e. everything behind your menu has been visualized; it has a Graphics object that you can use to get metrics for a given font just once.

You certainly do not want to do this in the paint method, which should be as light as possible. I would hang this code on a listener that gets called when the component is first displayed. It can store the resulting FontMetrics object somewhere where you can access it later, or in the paint method to draw these menu boxes.

Instead of defining measurements of menu graphics at the last moment, i.e. When paint ing, it might be a good idea to create some components to represent your menu. You can place these components on the glass panel for more information here , so that they pop up above everything else, and you will have the added bonus that these components can take mouse clicks and trigger listening events on them, and since they only capture events on their own geometry , you donโ€™t even need to determine which part of the menu was clicked, if at all possible.

Another advantage of using components here is that you can completely circumvent the requirement for messing around with font labels. There are ready-made menu items, or you can just use JLabels , and you can specify their alignment, you can use LayoutManager to size the boxes along the width of the largest label, etc.

+2
source

Assuming the menu text is corrected, you can pre-draw the BufferedImage text with alpha transparency and do your calculations then, Then, when you need the menu text, just draw an image.

You still have to do some offset calculations to center the image (assuming the panel size can change), but they should be relatively light.

+1
source

I think this is a good solution.

 private static HashMap<Font, FontMetrics> fontmetrics = new HashMap<Font, FontMetrics>(); public static FontMetrics getFontMetrics(Font font) { if (fontmetrics.containsKey(font)) { return fontmetrics.get(font); } FontMetrics fm = createFontMetrics(font); fontmetrics.put(font, fm); return fm; } private static FontMetrics createFontMetrics(Font font) { BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE); Graphics g = bi.getGraphics(); FontMetrics fm = g.getFontMetrics(font); g.dispose(); bi = null; return fm; } 
0
source

Adding to what Lonzac said, how about this:

 public static FontMetrics getFontMetrics(Font font){ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration config = gd.getDefaultConfiguration(); Canvas c = new Canvas(config); return c.getFontMetrics(font); } 

You can save the โ€œconfigโ€ variable as a static variable, so it is created once in a font class of the utility that contains other font-related information for your game / development environment. I think you could also do this with the canvas variable.

0
source

Source: https://habr.com/ru/post/1308594/


All Articles