JTextPane使用html垂直对齐文本和<img/>图像

时间:2017-03-27 08:52:03

标签: java html css jtextpane htmleditorkit

到目前为止,我已经尝试了大部分内容,我还读到,Java的HTML呈现非常有限,只能像HTML 3/2那样做。所以大多数现代CSS样式都不起作用。基本上我需要与几行垂直对齐的小图标(10x10px),我找不到一个有效的解决方案。我找到的唯一解决方法是创建一个表:

<table><tr><td>text</td><td><img></td><td>text</td></tr></table>

这是有效的,但是对于单行,如果有换行,它就不再明显了。

通常在浏览器中工作的所有其他解决方案在JTextPane中不起作用,例如为div中的表设置style="float: left;",或者仅使用img和div元素使用vertical-align: middle;

是否有一种“脏”的方法来操纵HTMLEditorKit的getViewFactory以将所有ImageViews返回到应该渲染它们的下方几个像素?

1 个答案:

答案 0 :(得分:0)

这是您编辑HTMLFactory的方法。在这里,我更改了InlineView,使我能够对角地穿过它。将它用于您自己的目的。

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.CSS;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.InlineView;

/**
 *
 * @author François Billioud
 */
public class HTMLBetterEditorKit extends HTMLEditorKit {

    private final HTMLEditorKit.HTMLFactory factory = new HTMLBetterFactory();
    @Override
    public ViewFactory getViewFactory() {
        return factory;
    }

    public static class HTMLBetterFactory extends HTMLEditorKit.HTMLFactory {
        @Override
        public View create(Element elem) {
            AttributeSet attrs = elem.getAttributes();
            Object elementName = attrs.getAttribute(AbstractDocument.ElementNameAttribute);
            Object o = (elementName != null) ? null : attrs.getAttribute(StyleConstants.NameAttribute);
            if (o == HTML.Tag.CONTENT) {
                return new StrikeView(elem);
            }
            return super.create(elem);
        }

        private class StrikeView extends InlineView {
            public StrikeView(Element elem) { super(elem); }

            public void paint(Graphics g, Shape allocation) {
                setStrikeThrough(false);//We will do that ourselves
                super.paint(g, allocation);
                Object textDecorationValue = getAttributes().getAttribute(CSS.Attribute.TEXT_DECORATION);
                if(textDecorationValue!=null && textDecorationValue.toString().equals("line-through")) {
                    paintStrikeLine(g, allocation);
                }
            }

            //paints the strike line
            public void paintStrikeLine(Graphics g, Shape a) {
                int y = a.getBounds().y+a.getBounds().height/2;
                int x1 = (int) a.getBounds().getX();
                int x2 = (int) (a.getBounds().getX() + a.getBounds().getWidth());

                Stroke oldStroke = ((Graphics2D)g).getStroke();
                ((Graphics2D)g).setStroke(new BasicStroke(2));
                g.drawLine(x1, y, x2, y);
                ((Graphics2D)g).setStroke(oldStroke);
            }
        }
    }
}

您只需将BetterHTMLEditorKit设置为JTextPane的EditorKit即可。

关于如何编辑图像的渲染方式,只需创建一个FloatView。问题是您需要编辑段落和文本在浮动图像周围呈现的方式,因此您需要重新定义BlockView和InlineView。所以工作并不容易。但如果你成功了,不要犹豫分享!

检查HTMLEditorKit.create方法,以便更好地了解视图生成过程中发生的情况。

祝你好运

修改 在仔细阅读了您的问题之后,我意识到您不想呈现float属性,只需要垂直对齐...为此,您有setAlignmentY。将其设置为0.5以进行中间对齐。对于JLabel,您可能还需要使用setVerticalAlignmentsetVerticalTextPosition