如何使用代号一准确获取绘制字符串的宽度(以像素为单位)?
How to accurately get the width of a drawn String (in pixel) with Codename One?
我正在尝试在代号一中的图像上准确放置一段短文本。我根据文本的宽度计算文本应该开始的位置,以便它显示在中间。
但是我从
得到的文本宽度
myFont.stringWidth(myStringToMeasure);
总是比实际绘制的文本大很多(在绘制文本的图形周围绘制了一个矩形)。因此文本看起来根本不居中。这是我从模拟器中得到的。
我试图将 myString 中每个字符的宽度与
求和
for (char c : myString.toCharArray()) {
stringWidth += myFont.charWidth(c);
}
但结果比上一个更大(几乎是原来的两倍)。
我是否误用了 stringWidth 方法?有没有办法可靠地获取绘制字符串的宽度?
注意:我刚刚在设备上试了一下,文本看起来和预期的一样。是我运气好还是它可以在其他真实设备上运行?
编辑 1:
这很奇怪,我知道@Shai 是对的,但我无法让它工作!如果我只是在我的方法中加入他的代码片段,我会得到完全不同的结果:
// width and height are the Graphics width and height that
// has been created via Image.createImage(myImage.getWidth(), myImage.getHeight())
public void paintOnBackground(Graphics g,
int width, int height) {
Font myFont = g.getFont();
g.setFont(myFont);
int w = myFont.stringWidth("Hi World");
int h = myFont.getHeight();
// Added just to see the background
g.setColor(0x0000FF);
g.fillRect(0, 0, width, height);
g.setColor(0xff0000);
// Because g.getTranslateX() is equivalent to getX() (not available here)
int x = g.getTranslateX() + width / 2 - w / 2;
int y = g.getTranslateY() + height / 2 - h / 2;
// The rectangle is centered
g.drawRect(x, y, w, h, 20); // large thickness to see it at a glance!
// The string is outside the rectangle
g.drawString("Hi World", x, y);
我什至没有得到@Shai 的结果:
知道我做错了什么吗?
编辑 2:好的,如果我在设备 (Android 4.4) 上测试它,该字符串将出现在 Shai 的屏幕截图中。 所以看起来这是一个与模拟器相关的问题(所有皮肤/Linux/Eclipse 4.5)! Shai 的代码(实际上也是我的)在真实设备上运行良好。
编辑 3:问题已解决:将项目库从 114 升级到 115 解决了问题 => 请参阅
如有任何帮助,我们将不胜感激!
干杯
根据定义,字符宽度将不准确,因为字符可能单独绘制不同。
当使用相同的字体对象时,字符串宽度在任何地方都应该完全准确:
Form f = new Form("Width", new BorderLayout());
f.add(BorderLayout.CENTER, new Component() {
@Override
protected void initComponent() {
super.initComponent();
setUIID("Label");
}
@Override
public void paint(Graphics g) {
Font myFont = getStyle().getFont();
g.setFont(myFont);
int w = myFont.stringWidth("Hi World");
int h = myFont.getHeight();
g.setColor(0xff0000);
int x = getX() + getWidth() / 2 - w / 2;
int y = getY() + getHeight() / 2 - h / 2;
g.drawRect(x, y, w, h);
g.drawString("Hi World", x, y);
}
});
f.show();
并使用不同的字体...
@Override
protected void initComponent() {
super.initComponent();
setUIID("Label");
Font handleeFont = Font.createTrueTypeFont("Handlee", "Handlee-Regular.ttf").
derive(Font.getDefaultFont().getHeight(), Font.STYLE_PLAIN);
Font handleeFontLarge = handleeFont.derive(handleeFont.getHeight() * 1.5f, Font.STYLE_PLAIN);
getUnselectedStyle().setFont(handleeFontLarge);
}
我正在尝试在代号一中的图像上准确放置一段短文本。我根据文本的宽度计算文本应该开始的位置,以便它显示在中间。
但是我从
得到的文本宽度myFont.stringWidth(myStringToMeasure);
总是比实际绘制的文本大很多(在绘制文本的图形周围绘制了一个矩形)。因此文本看起来根本不居中。这是我从模拟器中得到的。
我试图将 myString 中每个字符的宽度与
求和for (char c : myString.toCharArray()) {
stringWidth += myFont.charWidth(c);
}
但结果比上一个更大(几乎是原来的两倍)。
我是否误用了 stringWidth 方法?有没有办法可靠地获取绘制字符串的宽度?
注意:我刚刚在设备上试了一下,文本看起来和预期的一样。是我运气好还是它可以在其他真实设备上运行?
编辑 1:
这很奇怪,我知道@Shai 是对的,但我无法让它工作!如果我只是在我的方法中加入他的代码片段,我会得到完全不同的结果:
// width and height are the Graphics width and height that
// has been created via Image.createImage(myImage.getWidth(), myImage.getHeight())
public void paintOnBackground(Graphics g,
int width, int height) {
Font myFont = g.getFont();
g.setFont(myFont);
int w = myFont.stringWidth("Hi World");
int h = myFont.getHeight();
// Added just to see the background
g.setColor(0x0000FF);
g.fillRect(0, 0, width, height);
g.setColor(0xff0000);
// Because g.getTranslateX() is equivalent to getX() (not available here)
int x = g.getTranslateX() + width / 2 - w / 2;
int y = g.getTranslateY() + height / 2 - h / 2;
// The rectangle is centered
g.drawRect(x, y, w, h, 20); // large thickness to see it at a glance!
// The string is outside the rectangle
g.drawString("Hi World", x, y);
我什至没有得到@Shai 的结果:
知道我做错了什么吗?
编辑 2:好的,如果我在设备 (Android 4.4) 上测试它,该字符串将出现在 Shai 的屏幕截图中。 所以看起来这是一个与模拟器相关的问题(所有皮肤/Linux/Eclipse 4.5)! Shai 的代码(实际上也是我的)在真实设备上运行良好。
编辑 3:问题已解决:将项目库从 114 升级到 115 解决了问题 => 请参阅
如有任何帮助,我们将不胜感激!
干杯
根据定义,字符宽度将不准确,因为字符可能单独绘制不同。
当使用相同的字体对象时,字符串宽度在任何地方都应该完全准确:
Form f = new Form("Width", new BorderLayout());
f.add(BorderLayout.CENTER, new Component() {
@Override
protected void initComponent() {
super.initComponent();
setUIID("Label");
}
@Override
public void paint(Graphics g) {
Font myFont = getStyle().getFont();
g.setFont(myFont);
int w = myFont.stringWidth("Hi World");
int h = myFont.getHeight();
g.setColor(0xff0000);
int x = getX() + getWidth() / 2 - w / 2;
int y = getY() + getHeight() / 2 - h / 2;
g.drawRect(x, y, w, h);
g.drawString("Hi World", x, y);
}
});
f.show();
并使用不同的字体...
@Override
protected void initComponent() {
super.initComponent();
setUIID("Label");
Font handleeFont = Font.createTrueTypeFont("Handlee", "Handlee-Regular.ttf").
derive(Font.getDefaultFont().getHeight(), Font.STYLE_PLAIN);
Font handleeFontLarge = handleeFont.derive(handleeFont.getHeight() * 1.5f, Font.STYLE_PLAIN);
getUnselectedStyle().setFont(handleeFontLarge);
}