I'm trying to draw random text with fontSize
based on word frequency on the BufferedImage using the drawString(word, x, y)
with random x,y values. Unfortunately it draws the random text that is overlaping. The image frame size is 1200 x 650 and the random numbers for x, y are between these values. Here's my code:
Random rand = new Random();
Font f = getRandomFont(fontSize);
FontMetrics metrics = graphics.getFontMetrics(f);
AffineTransform affinetransform = new AffineTransform();
FontRenderContext frc = new FontRenderContext(affinetransform,true,true);
int textwidth = (int)(f.getStringBounds(word, frc).getWidth());
int textheight = (int)(f.getStringBounds(word, frc).getHeight());
graphics.setColor(Color.red);
graphics.setFont(f);
int x = textwidth + rand.nextInt(800);
int y = -textheight + rand.nextInt(800);
graphics.drawString(word, x , y );
First, fonts are drawn around the "base line", that is, the
y
position represents the baseline, so the text can grow above it and below it...So, instead of using
-textheight
, you should be usingFontMetrics#getAscent
Second, you need to keep track of all the previous locations text was painted, you could do this by using
FontMetrics#getStringBounds
, which returns aRectangle2D
and simply keep a list of this, which you can iterate over to check if the new text intersects any other, as an example...The red rectangles are just for demonstration purposes and you can get rid of those.
This does, however, demonstrate a small problem, not all the text fills all of the rectangle.
A more complex solution would be to use a
TextLayout
to generate aShape
of the text, which would allow words to be grouped much closed together.Have a look at Assigning a image to a String for a demonstration of how this can be generated
Shape
for the text as seen in this answer.