Hi All,
I am hoping this is the right subforum as I could not find a 'Graphics' subforum.
I have a question regarding initiating a BufferedImage just for the use of a FontMetrics. To be short: how dirty is the code below? But let me explain the problem, first.
I want to do a couple of things, one of them is to draw a rectangle as a background behind a couple of strings. As the string can differ in length, so need the rectangle. Also I do some other calculations based on the strings width. For instance, the position where every string needs to be drawn.
I use FontMetrics to get the width of the string(s). To use FontMetrics you need a Graphics variable, if I understood correctly. Therefore, I assume the most logical place to use FontMetrics, would be the method is which you paint. However, in my code a lot (100+) of calculations needs to be done based on this string widths. As all calculations needs to be done once, I would like to do the calculations only once (using the constructor) instead of calculating it every ‘repaint’. I assume this would (drastically) boost the performance of my game loop.
This led me to another problem. I call the constructor (/ create the object) in different methods, none being a paintable method. So, when I call the constructor I do not have a Graphics variable. Can anyone tell me how wrong and dirty it is to temporarily create a (new) bufferedImage with a Graphics variable, please? If this implementation is (horribly) wrong, can you tell me what the better solution is, please?
Below I have an image of my architecture, just to clarify if needed.
I created a (simplified) workable demo to show how I ‘dirty’ implemented a new BufferedImage.
import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; public class MetricsDemo { MetricsDemo() { Font contentFont = new Font("Arial", Font.PLAIN, 16); String messageText = "A text just for demonstration purposes."; BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); Graphics gTemp = image.getGraphics(); FontMetrics metrics = gTemp.getFontMetrics(contentFont); int stringLength = metrics.stringWidth(messageText); int stringHeight = metrics.getHeight(); System.out.printf("Text: %s \nLenght: %s, height: %s \n", messageText, stringLength, stringHeight); } public void render(Graphics2D g) { // In my real code this method is later called to draw the MetricsDemo. } public static void main(String[] args) { new MetricsDemo(); } }
Below the shortened architecture of my program. The Launcher class will create a GamePanel, which gets to the LevelState class via the GameStateManager. The LevelState uses multiple GameModes to draw specific objects, entities, menus, etc.. At some point in the PlanMode class I initiate the dPane which then does its calculations in its constructor.
After PlanMode initiated the dPane it will call the render method of the dPane. The dPane is temporarily, it will be ‘de-initiated’ when the user has given his input.