JTextComponentでサロゲートペアのテスト
Total: 8393, Today: 1, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JEditorPaneなどで数値文字参照やUnicodeエスケープを使ってサロゲートペアのテストをします。
Screenshot

Advertisement
Source Code Examples
URL url = getClass().getResource("SurrogatePair.html");
try (Reader reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8)) {
editor1.read(reader , "html");
} catch (Exception ex) {
editor1.setText(
"<html><p>(��) (𦹀)<br />(��) (𠮟)</p></html>");
}
JEditorPane editor2 = new JEditorPane();
// editor2.setFont(new Font("IPAexGothic", Font.PLAIN, 24));
editor2.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
editor2.setText("(\uD85B\uDE40) (\u26E40)\n(\uD842\uDF9F) (\u20B9F)");
View in GitHub: Java, KotlinDescription
以下、サロゲートペア対応フォントを使えるようにしてテストしています。Java Web Startで起動した場合、このサンプルのbrowseボタンでjarファイル内のSurrogatePair.htmlを表示することはできません。
- 上: 数値文字参照(
Numeric character reference)- Bug ID: 6836089 Swing HTML parser can't properly decode codepoints outside the Unicode Plane 0 into a surrogate pairで修正されたので、
𦹀などでも正常に文字が表示される(上記のスクリーンショットのように文字化けしない) JEditorPane(HTMLEditorKit)の場合JEditorPane+��:OKJEditorPane+𦹀:NGOK
- Bug ID: 6836089 Swing HTML parser can't properly decode codepoints outside the Unicode Plane 0 into a surrogate pairで修正されたので、
- ブラウザ(試したのは
IE,FireFox,Chrome,Opera)の場合Browser+��:NGBrowser+𦹀:OK
- 下:
Unicodeエスケープ(Unicode escapes)JEditorPane+\uD85B\uDE40:OKJEditorPane+\u26E40:NG
JTextComponentとブラウザでサロゲートペアの表現が異なるためこれらの文字をどちらの環境でも正しく表示したい場合は数値文字参照やUnicodeエスケープは使用せずソースコードなどをUTF-8にしてそのまま𦹀や𠮟と書く(メモ帳などの対応済みエディタで)ほうが良さそうWindows 7、JDK 1.7.0_02の環境ではJTextComponentからメモ帳などにサロゲートペアの文字をコピーペーストは可能だが、逆にメモ帳やブラウザからJTextComponentにサロゲートペアの文字をコピーペーストは不可JTextComponentは異体字セレクタに対応してない- フォントを
IVSに対応しているIPAmj明朝などに変更し異体字セレクタ付き文字列のあるUTF-8のテキストをJTextAreaなどに読み込んでも異体字セレクタが〓になる - 数値文字参照、
Unicodeエスケープを使う方法でも〓になる - Java IVSの異体字を元の字と同一視して比較する - terazzoの日記のように、
VSをUTF-16に(例えばU+E0101を\uDB40\uDD01に)してもJTextComponentでは駄目
- フォントを
- 参考メモ: MS IVSアドインでDTPにはどんな影響があるのか - ちくちく日記
Adobe-Japan1 collection:小塚明朝 Pr6NなどHanyo-Denshi collection:IPAmj明朝など
Windows 10 64bit、JDK 1.8.0_112、小塚明朝 Pr6N R(KozMinPr6N-Regular.otf)でFont.createFont(...)を使ってFontを作成するとIllegalArgumentExceptionが発生する場合がある
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Length must be >= 0. at javax.swing.text.GlyphPainter2.getBoundedPosition(GlyphPainter2.java: 205)
import java.awt.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public class OTFTest {
public JComponent makeUI() {
JTextArea textArea = new JTextArea("1234567890\n \uD85B\uDE40");
String str = "file:///C:/Program Files (x86)/Adobe/Acrobat 2015/Resource/CIDFont/KozMinPr6N-Regular.otf";
//String str = "file:///C:/Program Files (x86)/Adobe/Reader 11.0/Resource/CIDFont/KozMinPr6N-Regular.otf";
//String str = "file:///C:/Windows/Fonts/meiryo.ttc";
//String str = "file:///C:/Windows/Fonts/ipaexg.ttf";
//String str = "file:///C:/Windows/Fonts/A-OTF-ShinGoPro-Regular.otf";
try (InputStream is = new URL(str).openStream()) {
//textArea.setFont(Font.createFont(Font.TRUETYPE_FONT, is));
textArea.setFont(Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(32f));
} catch (IOException | FontFormatException ex) {
ex.printStackTrace();
}
JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(textArea));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new OTFTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
Reference
- Java Font Support - OpenType : Java Glossary
- OpenType (Java Platform SE 8)
- Java access files in jar causes java.nio.file.FileSystemNotFoundException - Stack Overflow