2

Two questions in one, but I have a very short test case demonstrating my problems:

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

When I use it I get:

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

and this image produced:

Numbers.png

My questions:

  1. How to force the DecimalFormat to use dot and not comma, without switching locale?
  2. The w seems to be correct, but what is wrong with 0 as the height - why are numbers printed offscreen?

Thank you! Alex

UPDATE:

I've ended up using Locale. The str.replace(".", ",") comment is cool too.

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"));
    }
}
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
  • You're not using `h`. Instead, you're hard-coding a `0` for the height of your drawn string... – mre Jul 14 '11 at 18:15
  • Yes - true, I don't use h yet. I wonder why isn't 0,0 the upper left corner of the text? – Alexander Farber Jul 14 '11 at 18:17
  • 1
    Read the [specs](http://download.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#drawString%28java.lang.String,%20float,%20float%29). – mre Jul 14 '11 at 18:19

1 Answers1

5

For 1: You can specify the format using format.applyLocalizedPattern("#00.0#"); instead of format.setGroupingUsed(false);

Another option is to use custom format symbols:

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

More information about localized patterns and some examples can be found here: http://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.html and http://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.html#numberpattern

For your second question, When you use g2d.drawString(str, x, y) the baseline is at x,y not the top left position as when you draw a rectangle. The baseline is basically the bottom of letters like a, b, c. Commas and letters like g, j, y extend below the baseline. You basically need to add the height of the text to the y position where you want to display the text.

Riaan Cornelius
  • 1,933
  • 1
  • 14
  • 17
  • Unfortunately format.applyLocalizedPattern("#00.0#") gives me exception: Malformed pattern "#00.0#" – Alexander Farber Jul 14 '11 at 18:16
  • Weird... That works for me. You can look at the following links for more information and examples: http://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.html http://download.oracle.com/javase/tutorial/i18n/format/decimalFormat.html#numberpattern – Riaan Cornelius Jul 14 '11 at 18:20
  • Try format.applyLocalizedPattern("###.##"); it might work better. – Riaan Cornelius Jul 14 '11 at 18:26
  • With format.applyLocalizedPattern("###.##") it unfortunately prints: 0: 1.00.00 1: 2.00.00 2: 30.00 – Alexander Farber Jul 14 '11 at 18:55
  • You probably just need to put back the format.setGroupingUsed(false); Also, look at my alternative option, I think that might be more consistent, since the other options obviously still take the locale into consideration. – Riaan Cornelius Jul 14 '11 at 18:57