Q:

java calculate number of printed characters on console to underline

I have a console app which prints a menu and get some input etc. The menu system has titles I underline:
 Main Menu
 =========

The title can be of varying size so my first attempt was to take the string length and print that many of the designated underline character. Unfortunately this doesn't work in our Japanese locale. The titles are stored in .properties files and fetched using the ResourceBundle class.
I saw some possible solutions in StackOverflow which seem mainly related to GUIs so have not helped:
public static int getGraphemeCount(String text) {
   int graphemeCount = 0;
   BreakIterator graphemeCounter = BreakIterator.getCharacterInstance();
   graphemeCounter.setText(text);
   while (graphemeCounter.next() != BreakIterator.DONE) 
      graphemeCount++;
      return graphemeCount;
}
public static void outputTitle(String title,char underChar) {
   String underline = repeats(underChar,getGraphemeCount(title));
   System.out.printf("\n\t%s\n\t%s\n",title,underline);
}

There's an extra wrinkle in that not all the text will be translated (e.g. company or product names).
[update]
Having had a closer look at the output it appears the individual Japanese characters take up two places for each english character. Is there a function to determine this on a per character basis?
[update]
Any thoughts?
Simon

A:

Terminals typically show CJK characters using two slots instead of just one, so you have to count each of them as two characters. There are also "half width characters" that occupy a single slot. The only way to get the  visual string length is looping over the characters, counting full width characters as two.
The width of a character can be looked up as the Unicode character property EAST_ASIAN_WIDTH. Unfortunately the standard API does not provide any method for looking up this property, but the ICU4J library does: 
char c = ...;
int width;
switch (UCharacter.getIntPropertyValue(c, UProperty.EAST_ASIAN_WIDTH)) {
    case UCharacter.EastAsianWidth.WIDE:
    case UCharacter.EastAsianWidth.FULLWIDTH:
        width = 2; break;
    default:
        width = 1;
}

Here's the character data if you can't use ICU4J. There's probably a lot of overlap between this data and the assignment of characters to blocks or scripts; I would guess most HAN characters are wide for example.

