半伪代码:
public Font scaleFont(
String text, Rectangle rect, Graphics g, Font font) {
float fontSize = 20.0f;
font = g.getFont().deriveFont(fontSize);
int width = g.getFontMetrics(font).stringWidth(text);
fontSize = (rect.width / width ) * fontSize;
return g.getFont().deriveFont(fontSize);
}
迭代的派生:
/**
* Adjusts the given {@link Font}/{@link String} size such that it fits
* within the bounds of the given {@link Rectangle}.
*
* @param label Contains the text and font to scale.
* @param dst The bounds for fitting the string.
* @param graphics The context for rendering the string.
* @return A new {@link Font} instance that is guaranteed to write the given
* string within the bounds of the given {@link Rectangle}.
*/
public Font scaleFont(
final JLabel label, final Rectangle dst, final Graphics graphics ) {
assert label != null;
assert dst != null;
assert graphics != null;
final var font = label.getFont();
final var text = label.getText();
final var frc = ((Graphics2D) graphics).getFontRenderContext();
final var dstWidthPx = dst.getWidth();
final var dstHeightPx = dst.getHeight();
var minSizePt = 1f;
var maxSizePt = 1000f;
var scaledFont = font;
float scaledPt = scaledFont.getSize();
while( maxSizePt - minSizePt > 1f ) {
scaledFont = scaledFont.deriveFont( scaledPt );
final var layout = new TextLayout( text, scaledFont, frc );
final var fontWidthPx = layout.getVisibleAdvance();
final var metrics = scaledFont.getLineMetrics( text, frc );
final var fontHeightPx = metrics.getHeight();
if( (fontWidthPx > dstWidthPx) || (fontHeightPx > dstHeightPx) ) {
maxSizePt = scaledPt;
}
else {
minSizePt = scaledPt;
}
scaledPt = (minSizePt + maxSizePt) / 2;
}
return scaledFont.deriveFont( (float) Math.floor( scaledPt ) );
}
假设您要向具有矩形边界的组件添加标签,以便标签完全填充组件的区域。人们可以这样写:r
final Font DEFAULT_FONT = new Font( "DejaVu Sans", BOLD, 12 );
final Color COLOUR_LABEL = new Color( 33, 33, 33 );
// TODO: Return a valid container component instance.
final var r = getComponent().getBounds();
final var graphics = getComponent().getGraphics();
final int width = (int) r.getWidth();
final int height = (int) r.getHeight();
final var label = new JLabel( text );
label.setFont( DEFAULT_FONT );
label.setSize( width, height );
label.setForeground( COLOUR_LABEL );
final var scaledFont = scaleFont( label, r, graphics );
label.setFont( scaledFont );