java getstringbounds,FontMetrics.getStringBounds的AttributedString给出错误的结果呢?

As shown in the following picture, an AttributedString is drawn on a JPanel (500X500).

The FontMetrics.getStringBounds() of that AttributedString gives a width of 164.0, as indicated by the trace output.

java.awt.geom.Rectangle2D$Float[x=0.0,y=-12.064453,w=164.0,h=15.09375]

However, the picture suggests the width should be 300-400 (because the width of the panel is 500).

Could you help to comment the reason and the workaround ?

vkHBr.png

MyJFrame.java

import javax.swing.*;

import java.awt.*;

import java.awt.font.TextAttribute;

import java.text.AttributedString;

class MyJPanel extends JPanel {

MyJPanel() {

setPreferredSize(new Dimension(500,500));

}

@Override

public void paintComponent(Graphics gold) {

super.paintComponent(gold);

Graphics2D g = (Graphics2D)gold;

//

AttributedString text = new AttributedString("Bunny rabits and flying ponies");

text.addAttribute(TextAttribute.FONT, new Font("Arial", Font.BOLD, 24), 0, "Bunny rabits".length());

text.addAttribute(TextAttribute.FOREGROUND, Color.RED, 0, "Bunny rabits".length());

text.addAttribute(TextAttribute.FONT, new Font("Arial", Font.BOLD & Font.ITALIC, 32), 17, 17 + "flying ponies".length());

text.addAttribute(TextAttribute.FOREGROUND, Color.BLUE, 17, 17 + "flying ponies".length());

FontMetrics fm = g.getFontMetrics();

System.out.println(fm.getStringBounds(text.getIterator(), 0, text.getIterator().getEndIndex(), g));

g.drawString(text.getIterator(), 50, 50);

//

g.dispose();

}

}

public class MyJFrame extends JFrame {

public static void main(String[] args) {

MyJFrame frame = new MyJFrame();

frame.setContentPane(new MyJPanel());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setVisible(true);

}

}

解决方案

FontMetrics fontMetrics = graphics.getFontMetrics() returns a FontMetrics object based on the single font currently set on the graphics object. You are not changing the font used by graphics explicitly so it uses the default font designated for JPanel by the current L&F.

FontMetrics methods related to bounds calculation accept a "simple" CharacterIterator (which does not provide font information) instead of AttributedCharacterIterator (which does). Hence fontMetrics.getStringBounds() simply calculates the text bounds based on the single font of the same size.

You need to use java.awt.font.TextLayout to determine the proper bounds when using AttributedCharacterIterator with different fonts and font sizes:

TextLayout textLayout = new TextLayout(

text.getIterator(),

g.getFontRenderContext()

);

Rectangle2D.Float textBounds = ( Rectangle2D.Float ) textLayout.getBounds();

g.drawString( text.getIterator(), 50, 50 );

// lets draw a bounding rect exactly around our text

// to be sure we calculated it properly

g.draw( new Rectangle2D.Float(

50 + textBounds.x, 50 + textBounds.y,

textBounds.width, textBounds.height

) );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值