【问题标题】:Using DecimalFormat (force dot) and drawString() (y seems to be wrong)使用 DecimalFormat(强制点)和 drawString()(y 似乎是错误的)
【发布时间】:2011-07-14 18:07:26
【问题描述】:

两个问题合二为一,但我有一个非常简短的测试用例来展示我的问题:

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.imageio.*;

public class Numbers {

    public static void main(String[] args) throws IOException {
        double[] numbers = { 10000.12, 20000.23, 3000.45 };
        DecimalFormat format = new DecimalFormat("0.00");
        format.setGroupingUsed(false);
        BufferedImage image = new BufferedImage(400, 150, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setColor(Color.BLACK);
        g2d.setBackground(Color.YELLOW);
        g2d.clearRect(0, 0, image.getWidth(), image.getHeight());
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setFont(new Font(Font.SANS_SERIF,Font.BOLD, 24));
        FontMetrics metrics = g2d.getFontMetrics();

        for (int i = 0; i < numbers.length; i++) {
            String str = format.format(numbers[i]);
            System.out.println(i + ": " + str);

            int w = metrics.stringWidth(str);
            int h = metrics.getHeight();
            int x = 100 * i;
            g2d.drawString(str, x - w/2, 0);
        }

        g2d.dispose();
        ImageIO.write(image, "PNG", new File("Numbers.png"));
    }
}

当我使用它时,我得到:

C:\Temp>javac -version
javac 1.6.0_24

C:\Temp>javac Numbers.java

C:\Temp>java Numbers
0: 10000,12
1: 20000,23
2: 3000,45

并生成了这张图片:

我的问题:

  1. 如何在不切换语言环境的情况下强制 DecimalFormat 使用点而不是逗号?
  2. w 似乎是正确的,但高度为 0 有什么问题 - 为什么数字会打印在屏幕外?

谢谢!亚历克斯

更新:

我最终使用了语言环境。 str.replace(".", ",") 注释也很酷。

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.imageio.*;

public class Numbers {

    public static void main(String[] args) throws IOException {
        double[] numbers = { 10000.12, 20000.23, 3000.45 };
        BufferedImage image = new BufferedImage(400, 150, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.setBackground(Color.GRAY);
        g2d.clearRect(0, 0, image.getWidth(), image.getHeight());
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setFont(new Font(Font.SANS_SERIF,Font.BOLD, 24));
        FontMetrics metrics = g2d.getFontMetrics();
        NumberFormat format = NumberFormat.getInstance(Locale.US);
        format.setGroupingUsed(false);
        if (format instanceof DecimalFormat) {
            ((DecimalFormat) format).applyPattern("0.00");
        }

        for (int i = 0; i < numbers.length; i++) {
            String str = format.format(numbers[i]);
            System.out.println(i + ": " + str);

            int w = metrics.stringWidth(str);
            int h = metrics.getHeight();
            int x = 100 * i;
            g2d.drawString(str, x - w/2, h);
        }

        g2d.dispose();
        ImageIO.write(image, "PNG", new File("Numbers.png"));
    }
}

【问题讨论】:

  • 你没有使用h。相反,您正在为绘制字符串的高度硬编码 0...
  • 是的 - 是的,我还没有使用 h。我想知道为什么文字的左上角不是0,0?
  • 阅读specs

标签: java graphics2d drawstring decimalformat


【解决方案1】:

对于 1:您可以使用 format.applyLocalizedPattern("#00.0#"); 而不是 format.setGroupingUsed(false); 指定格式

另一种选择是使用自定义格式符号:

DecimalFormatSymbols decimalSymbol = new DecimalFormatSymbols(Locale.getDefault());
decimalSymbol.setDecimalSeparator('.');
format.setGroupingUsed(false);

有关本地化模式的更多信息和一些示例可以在这里找到: http://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.htmlhttp://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.html#numberpattern

对于您的第二个问题,当您使用 g2d.drawString(str, x, y) 时,基线位于 x,y 而不是绘制矩形时的左上角。基线基本上是字母的底部,如 a、b、c。逗号和字母(如 g、j、y)延伸到基线以下。您基本上需要将文本的高度添加到要显示文本的y位置。

【讨论】:

  • 不幸的是 format.applyLocalizedPattern("#00.0#") 给了我异常:格式错误的模式“#00.0#”
  • 奇怪...这对我有用。您可以查看以下链接以获取更多信息和示例:download.oracle.com/javase/tutorial/i18n/format/…download.oracle.com/javase/tutorial/i18n/format/…
  • 试试 format.applyLocalizedPattern("###.##");它可能会更好。
  • 使用 format.applyLocalizedPattern("###.##") 不幸的是打印:0:1.00.00 1:2.00.00 2:30.00
  • 你可能只需要放回format.setGroupingUsed(false);另外,看看我的替代选项,我认为这可能更一致,因为其他选项显然仍然考虑语言环境。
猜你喜欢
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 2022-10-26
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2014-04-18
  • 2012-10-21
相关资源
最近更新 更多