如何使用Codename One准确获取绘制的String(以像素为单位)的宽度?

时间:2016-06-21 17:07:53

标签: drawing codenameone

我正在尝试在Codename One中的图像上放置一个简短的文本。我根据文本的宽度计算文本应该开始的位置,使其显示为居中。

然而我从

得到的文字宽度
myFont.stringWidth(myStringToMeasure);

总是比实际绘制的文本大得多(在绘制文本的图形周围绘制一个矩形)。因此,文本看起来并不是中心。这是我从模拟器得到的。

Part of the background image with the text over it (simulator)

我尝试将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的结果:

Generated image that reflects what is on the simulator's screen (the grey background comes from Gimp)

知道我做错了吗?

编辑2:好的,如果我在设备上测试它(Android 4.4),字符串会出现在Shai的屏幕截图中。 所以看起来这是一个与模拟器相关的问题(所有皮肤/ Linux / Eclipse 4.5)! Shai的代码(我的确也是如此)在真实设备上运行良好。

编辑3:问题解决:将项目库从114升级到115修复了问题=>见this other SO question which was related

非常感谢任何帮助!

干杯

1 个答案:

答案 0 :(得分:1)

根据定义,字符宽度将不准确,因为字符可能会单独绘制。

使用相同的Font对象时,字符串宽度应完全准确:

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();

enter image description here

使用不同的字体......

@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);
}

enter image description here