FontMetrics.getStringBounds的AttributedString给出错误的结果呢? [英] FontMetrics.getStringBounds for AttributedString gives wrong result?
问题描述
如下面的图所示,构造一个AttributedString画在一个JPanel(500X500)。
的 FontMetrics.getStringBounds()
的AttributedString的给出了164.0的宽度,通过跟踪输出指示。
java.awt.geom.Rectangle2D中$浮法[X = 0.0,Y = -12.064453,W = 164.0,H = 15.09375]
然而,该图片表明宽度应300-400(因为面板的宽度是500)。
你能帮评论的原因和解决方法?
MyJFrame.java
进口的javax.swing *。
进口java.awt中的*。
进口java.awt.font.TextAttribute中;
进口java.text.AttributedString;类MyJPanel继承JPanel {
MyJPanel(){
集preferredSize(新尺寸(500,500));
} @覆盖
公共无效的paintComponent(图形金){
super.paintComponent方法(金);
Graphics2D的G =(Graphics2D的)金;
//
AttributedString文本=新AttributedString(兔子RABiTS基带上和飞行小马);
text.addAttribute(TextAttribute.FONT,新的字体(宋体,Font.BOLD,24),0,兔子RABiTS基带上。长度());
text.addAttribute(TextAttribute.FOREGROUND,Color.RED,0,兔子RABiTS基带上。长度()); text.addAttribute(TextAttribute.FONT,新的字体(宋体,Font.BOLD&安培; Font.ITALIC,32),17,17 +飞小马。长度());
text.addAttribute(TextAttribute.FOREGROUND,Color.BLUE,17,17 +飞小马。长度()); FontMetrics对象FM = g.getFontMetrics(); 的System.out.println(fm.getStringBounds(text.getIterator(),0,text.getIterator()为getEndIndex(),G));
g.drawString(text.getIterator(),50,50);
//
g.dispose();
}
}公共类MyJFrame扩展的JFrame { 公共静态无效的主要(字串[] args){
MyJFrame帧=新MyJFrame();
frame.setContentPane(新MyJPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(真);
}
}
FontMetrics对象的FontMetrics = graphics.getFontMetrics()
返回的FontMetrics
基于单字体对象目前在图形
对象设置。所以它使用当前L&放大器指定为的JPanel
默认字体你是不是改变由显卡使用的字体
明确; F。
的FontMetrics
有关边界的计算方法接受一个简单的CharacterIterator
(不提供字体信息),而不是的的AttributedCharacterIterator
(它)。因此, fontMetrics.getStringBounds()
简单计算基于相同尺寸的单一字体文本范围。
您需要使用 java.awt.font.TextLayout中的
时使用,以确定正确的边界的AttributedCharacterIterator
不同字体和字体大小:
的TextLayout TextLayout的=新的TextLayout(
text.getIterator(),
g.getFontRenderContext()
);
Rectangle2D.Float textBounds =(Rectangle2D.Float)textLayout.getBounds();g.drawString(text.getIterator(),50,50);
//正好可以绘制一个矩形边框围绕我们的文字
//以确保我们正确地计算出它
g.draw(新Rectangle2D.Float(
50 + textBounds.x,50 + textBounds.y,
textBounds.width,textBounds.height
));
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 ?
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
) );
这篇关于FontMetrics.getStringBounds的AttributedString给出错误的结果呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!