Swing/SurrogatePair のバックアップの現在との差分(No.2)
TITLE:JTextComponentでサロゲートペアのテスト
Posted by aterai at 2012-05-14
JTextComponentでサロゲートペアのテスト
JEditorPaneなどで数値文字参照やUnicodeエスケープを使ってサロゲートペアのテストをします。- category: swing folder: SurrogatePair title: JTextComponentでサロゲートペアのテスト tags: [JEditorPane, JTextComponent, Unicode, Fixed] author: aterai pubdate: 2012-05-14T11:54:26+09:00 description: JEditorPaneなどで数値文字参照やUnicodeエスケープを使ってサロゲートペアのテストをします。 image:
概要
JEditorPane
などで数値文字参照やUnicode
エスケープを使ってサロゲートペアのテストをします。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spandel
final URL url = getClass().getResource("SurrogatePair.html");
#spanend
#spandel
try{
#spanend
editor1.read(new InputStreamReader(url.openStream(), "UTF-8"), "html");
#spandel
}catch(Exception ex) {
#spanend
editor1.setText("<html><p>(��) (𦹀)<br />(��) (𠮟)</p></html>");
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
URL url = getClass().getResource("SurrogatePair.html");
#spanend
#spanadd
try (Reader reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8)) {
#spanend
editor1.read(reader , "html");
#spanadd
} catch (Exception ex) {
#spanend
editor1.setText(
"<html><p>(��) (𦹀)<br />(��) (𠮟)</p></html>");
}
JEditorPane editor2 = new JEditorPane();
#spandel
//editor2.setFont(new Font("IPAexGothic", Font.PLAIN, 24));
#spanend
#spanadd
// editor2.setFont(new Font("IPAexGothic", Font.PLAIN, 24));
#spanend
editor2.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
editor2.setText("(\uD85B\uDE40) (\u26E40)\n(\uD842\uDF9F) (\u20B9F)");
解説
以下、サロゲートペア対応フォントを使えるようにしてテストしています。Java Web Start で起動した場合、"browse"ボタンでSurrogatePair.htmlを表示することはできません。解説
以下、サロゲートペア対応フォントを使えるようにしてテストしています。Java Web Start
で起動した場合、このサンプルのbrowse
ボタンでjar
ファイル内のSurrogatePair.html
を表示することはできません。
- 上: 数値文字参照(Numeric character reference)
- JEditorPane(HTMLEditorKit)の場合
JEditorPane OK: �� JEditorPane NG: 𦹀
- JEditorPane(HTMLEditorKit)の場合
- 上: 数値文字参照(
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
+��
:OK
-
JEditorPane
+𦹀
: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 NG: �� Browser OK: 𦹀
- ブラウザ(試したのは
IE
,FireFox
,Chrome
,Opera
)の場合-
Browser
+��
:NG
-
Browser
+𦹀
:OK
-
- 下: Unicodeエスケープ(Unicode escapes)
JEditorPane OK: \uD85B\uDE40 JEditorPane NG: \u26E40
- 下:
Unicode
エスケープ(Unicode escapes
)-
JEditorPane
+\uD85B\uDE40
:OK
-
JEditorPane
+\u26E40
:NG
-
JTextComponentとブラウザでサロゲートペアの表現が異なるようなので、これらの文字をどちらの環境でも正しく表示したい場合は、数値文字参照やUnicodeエスケープは使用せず、ソースコードなどをUTF-8にしてそのまま𦹀や𠮟と書く*1のがよさそうです。
-
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
では駄目
- フォントを
Windows7, JDK 1.7.0_02 の環境では、JTextComponentからメモ帳などにサロゲートペアの文字をコピーペーストは可能ですが、逆にメモ帳やブラウザからJTextComponentにサロゲートペアの文字をコピーペーストすることができないようです。
- 参考メモ: MS IVSアドインでDTPにはどんな影響があるのか - ちくちく日記
-
Adobe-Japan1 collection
:小塚明朝 Pr6N
など -
Hanyo-Denshi collection
:IPAmj明朝
など
-
現状ではJTextComponentは、異体字セレクタに対応していない?
- フォントをIVS(Adobe-Japan1-6)に対応している小塚明朝 Pr6N や IPAex明朝 などに変更して、数値文字参照、Unicodeエスケープを使っても下駄になったり、ソースコードをUTF-8にしても
以下のような IllegalArgumentException が発生するようです。 -
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)
- IllegalArgumentExceptionと異体字セレクタは関係なくて、Windows環境のJavaと'小塚明朝 Pr6N R'(OTFフォントだから?) と相性が悪いだけ?
#spanend #spanadd import java.awt.*; #spanend #spanadd import java.io.*; #spanend #spanadd import java.net.*; #spanend #spanadd import javax.swing.*; #spanend #spandel //**参考リンク #spanend #spandel **コメント [#qfcd8f76] #spanend #spanadd public class OTFTest { #spanend 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; } #spanadd #spanend public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } #spanadd #spanend 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); } #spanadd } #spanend #spanadd
参考リンク
- Java Font Support - OpenType : Java Glossary
- OpenType (Java Platform SE 8)
- Java access files in jar causes java.nio.file.FileSystemNotFoundException - Stack Overflow