Strange Unicode Behaviour of TextField

时间:2017-06-12 16:55:44

标签: java javafx unicode

UPDATE June 20

Summary:

Given the following:

String problemString = "é";

JavaFX8's TextField has trouble displaying the contents of problemString if it is set as follows:

aTextField.setText(problemString);

On Windows 10 the above with produce "МЃ" instead of "é", and on macOS 10.12 the TextField will display "é" but will be very buggy and effectively useless.

Also interesting to note is that the TextField has no problems with the contents of problemString being copied and pasted in on either operating system, only when using the setText() method.

UPDATE June 12

I have narrowed down the issue further. The é I am having problems with is not the precomposed é character (U+00E9) but rather is composed of e + ◌́.

Java will show these characters properly on macOS but the TextField is extremely glitchy and will not allow for editing of the text.

ORIGINAL

I have a program that reads in text, in unicode UTF-8 format, from a file and stores the content in String. At some point in the program the content of these strings is loaded into a TextField in order for the user to edit. My problem is that certain unicode characters are not display properly. However, if the text is saved back into a file, a new one or the old one, the content will be correct. Also to note, this happens only on Windows (10), on macOS (10.12) this problem does not occur. Any idea of what's causing this, or how to fix it?

For example:

I read in the character "é" from a text file and store it in a string. Upon displaying it in the TextField I will see "МЃ" and NOT "é". But, if I then continue with the program and save to a text file the file will have an "é" in it.

1 个答案:

答案 0 :(得分:1)

问题在于unicode允许存储字符的可能方式。在这种情况下,“é”有两种表示方式。

<强> 1。作为单个unicode字符,组成形式:

é(U + 00E9带有急性的拉丁文小写字母E)

<强> 2。作为两个字符的组合,分解形式:

e(U + 0065 LATIN SMALL LETTER E)

◌(U + 0301组合急性加速)

如果字符串是分解形式,TextField似乎不喜欢使用.setText()方法显示字符串。

我解决这个问题的方法是使用Java Normalizer Class

String fixedString = Normalizer.normalize(problemString, Normalizer.Form.NFC);
aTextField.setText(fixedString);

上面的代码使用Java Normalizer类将problemString从其分解形式转换为其组合形式,这个TextField似乎可以很好地使用它。