概要

JEditorPaneに配置したImgタグのvertical-alignをベースライン揃えに変更します。

サンプルコード

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));
        }
        AttributeSet attrs = elem.getAttributes();
        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 view;
      }
    };
  }
}
view all

解説

    • <img>タグで挿入した画像がインラインボックスからずれて表示される
    • img {align: middle; valign: middle; vertical-align: middle;}などの設定が無効
    • javax/swing/text/html/ImageView.javasetPropertiesFromAttributes()の実装は、以下のようにHTML.Attribute.VERTICAL_ALIGNではなくHTML.Attribute.ALIGNを使用することで、少なくともtop, middleが使用できるはずだが、Java 1.8.0_144ではこれらを設定しても全く効果がない?
      /**
       * 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()で使用するよう設定
    • 上記のサンプルでは、画像サイズをデフォルトフォントのサイズと同じに設定し、ベースラインも同じ値を使用するよう固定している
    • デフォルトのHTMLEditorKitのフォントとは異なるフォントが使用される?

参考リンク

コメント