Swing/HTMLImgBaseline の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/HTMLImgBaseline へ行く。
- Swing/HTMLImgBaseline の差分を削除
--- category: swing folder: HTMLImgBaseline title: JEditorPaneに配置したImgタグのvertical-alignを変更する tags: [JEditorPane, HTML] author: aterai pubdate: 2017-09-11T15:39:55+09:00 description: JEditorPaneに配置したImgタグのvertical-alignをベースライン揃えに変更します。 image: https://drive.google.com/uc?id=1SHPkR8vKbzKY6zpuM6eQL0c_ci02zOsLcw --- * 概要 [#summary] `JEditorPane`に配置した`Img`タグの`vertical-align`をベースライン揃えに変更します。 #download(https://drive.google.com/uc?id=1SHPkR8vKbzKY6zpuM6eQL0c_ci02zOsLcw) * サンプルコード [#sourcecode] #code(link){{ class ImgBaselineHTMLEditorKit extends HTMLEditorKit { @Override public ViewFactory getViewFactory() { return new HTMLEditorKit.HTMLFactory() { @Override public View create(Element elem) { View view = super.create(elem); if (view instanceof LabelView) { System.out.println("debug: " + view.getAlignment(View.Y_AXIS)); System.out.println( "debug: " + view.getAlignment(View.Y_AXIS)); } AttributeSet attrs = elem.getAttributes(); Object elementName = attrs.getAttribute(AbstractDocument.ElementNameAttribute); Object elementName = attrs.getAttribute( AbstractDocument.ElementNameAttribute); Object o = Objects.nonNull(elementName) ? null : attrs.getAttribute(StyleConstants.NameAttribute); if (o instanceof HTML.Tag) { HTML.Tag kind = (HTML.Tag) o; if (kind == HTML.Tag.IMG) { return new ImageView(elem) { @Override public float getAlignment(int axis) { // .8125f magic number... return axis == View.Y_AXIS ? .8125f : super.getAlignment(axis); return axis == View.Y_AXIS ? .8125f : super.getAlignment(axis); } }; } } return view; } }; } } }} * 解説 [#explanation] - 上 -- `<img>`タグで挿入した画像がインラインボックスからずれて表示される -- `img {align: middle; valign: middle; vertical-align: middle;}`などの設定が無効 -- `img {align: middle; valign: middle; vertical-align: middle;}`などを設定しても`HTMLEditorKit`では無効 -- `javax/swing/text/html/ImageView.java`の`setPropertiesFromAttributes()`の実装は、以下のように`HTML.Attribute.VERTICAL_ALIGN`ではなく`HTML.Attribute.ALIGN`を使用することで、少なくとも`top`、`middle`が使用できるはずだが`Java 1.8.0_144`ではこれらを設定しても全く効果がない? #code{{ /** * Update any cached values that come from attributes. */ // @see javax/swing/text/html/ImageView.java protected void setPropertiesFromAttributes() { StyleSheet sheet = getStyleSheet(); this.attr = sheet.getViewAttributes(this); // ... AttributeSet attr = getElement().getAttributes(); // Alignment. // PENDING: This needs to be changed to support the CSS versions // when conversion from ALIGN to VERTICAL_ALIGN is complete. Object alignment = attr.getAttribute(HTML.Attribute.ALIGN); vAlign = 1.0f; if (alignment != null) { alignment = alignment.toString(); if ("top".equals(alignment)) { vAlign = 0f; } else if ("middle".equals(alignment)) { vAlign = .5f; } } // ... }} - 下 -- `ImageView#getAlignment(...)`メソッドをオーバーライドして`vertical-align`を直接指定する`HTMLFactory`を作成し、`HTMLEditorKit#getViewFactory()`メソッドで使用するよう設定 -- 上記のサンプルでは、画像サイズをデフォルトフォントのサイズと同じに設定し、ベースラインも同じ値を使用するよう固定している * 参考リンク [#reference] - [https://bugs.openjdk.org/browse/JDK-5094219 JDK-5094219 JEditorPane doesn't recognize CSS vertical-align property - Java Bug System] - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/text/html/ImageView.html#getAlignment-int- ImageView#getAlignment(...) (Java Platform SE 8)] - [[JTextPaneに追加するコンポーネントのベースラインを揃える>Swing/InsertComponentBaseline]] * コメント [#comment] #comment #comment