Best way to determine optimal font size given some text in a rectangle
Hi Folks,
I have a preview panel in which I am showing some text for the current selected date using a date format.
I want to increase the size of the applied font so that itscales nicely when the panel in which it is drawn is resized.
I want to know the best way in terms of performance to achieve the target. I did some reading about AffineTransform and determining by checking ina loop which is the correct size, but it does not feel like a good way.
I would appreciate some tips.
Cheers.
Ravi
# 2
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
public class ScaledText extends JPanel {
String text = "Sample String";
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Font font = g2.getFont().deriveFont(16f);
g2.setFont(font);
FontRenderContext frc = g2.getFontRenderContext();
int w = getWidth();
int h = getHeight();
float[][] data = {
{ h/8f, w/3f, h/12f }, { h/3f, w/4f, h/8f }, { h*3/4f, w/2f, h/16f }
};
for(int j = 0; j < data.length; j++) {
float y = data[j][0];
float width = data[j][1];
float height = data[j][2];
float x = (w - width)/2f;
Rectangle2D.Float r = new Rectangle2D.Float(x, y, width, height);
g2.setPaint(Color.red);
g2.draw(r);
float sw = (float)font.getStringBounds(text, frc).getWidth();
LineMetrics lm = font.getLineMetrics(text, frc);
float sh = lm.getAscent() + lm.getDescent();
float xScale = r.width/sw;
float yScale = r.height/sh;
float scale = Math.min(xScale, yScale);
float sx = r.x + (r.width - scale*sw)/2;
float sy = r.y + (r.height + scale*sh)/2 - scale*lm.getDescent();
AffineTransform at = AffineTransform.getTranslateInstance(sx, sy);
at.scale(scale, scale);
g2.setFont(font.deriveFont(at));
g2.setPaint(Color.blue);
g2.drawString(text, 0, 0);
}
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new ScaledText());
f.setSize(400,400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}