java - JEdi​​torPane 正在删除 CSS 字体样式

标签 java html css swing jeditorpane

我正在尝试让 JEditorPane 保留任何 CSS 字体样式。不幸的是,它似乎将段落标签(以及其他标签)完全剥离,并将其转换为 A 标签的字体标签。

考虑以下示例:

import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
public class EditorPaneTest
{
    public static void main(String[] args)
    {
        String text = "<html><head></head><body><p style=\"padding-right: 10px; padding-left: 10px; font-size: 14px; line-height: 125%; font-family: Verdana;\">This is a test.</p>"
                + "<p><a href=\"http://www.google.com/\" style=\"font-size: 9px; margin-right: 10px; font-style: normal; font-family: Verdana;\">Google</a></p></body></html>";
        JEditorPane editorPane = new JEditorPane("text/html", text);
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(new JScrollPane(editorPane), BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        text = editorPane.getText();
        System.out.println(text);
    }
}

这会为 p 和 a 标签生成以下输出:

<p style="padding-left: 10px; padding-right: 10px; line-height: 125%">

<a href="http://www.google.com/" style="margin-right: 10px"><font size="9px" face="Verdana">Google</font></a>

如您所见,它保留了填充和边距样式,但去除了段落标签的字体样式,并将其转换为 A 标签的字体标签。

在调用 getText 之前,如果您显示它,它实际上会正确设置段落的样式。

我如何获取它以便它保留原样的字体属性?

最佳答案

好的,

确定问题肯定在 HTMLWriter 类中。不幸的是,他们并没有让重写这个类变得容易,但我相信我有它。

    import java.io.IOException;
    import java.io.Writer;
    import java.util.Enumeration;
    import java.util.Vector;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.MutableAttributeSet;
    import javax.swing.text.SimpleAttributeSet;
    import javax.swing.text.StyleConstants;
    import javax.swing.text.html.CSS;
    import javax.swing.text.html.HTML;
    import javax.swing.text.html.HTMLDocument;
    import javax.swing.text.html.HTMLWriter;

    public class FixedHTMLWriter extends HTMLWriter
    {
        private Vector                      tags                = new Vector(10);
        private Vector                      tagValues       = new Vector(10);
        private Vector                      tagsToRemove    = new Vector(10);
        private MutableAttributeSet convAttr            = new SimpleAttributeSet();
        private MutableAttributeSet oConvAttr       = new SimpleAttributeSet();

        public FixedHTMLWriter(Writer w, HTMLDocument doc, int pos, int len)
        {
            super(w, doc, pos, len);
        }

        AttributeSet convertToHTML(AttributeSet from, MutableAttributeSet to)
        {
            if (to == null)
            {
                to = convAttr;
            }
            to.removeAttributes(to);
            if (from != null)
            {
                Enumeration keys = from.getAttributeNames();
                String value = "";
                while (keys.hasMoreElements())
                {
                           Object key = keys.nextElement();
                    if (key instanceof CSS.Attribute)
                    {
                        value +=  key + ": " + from.getAttribute(key) + ";";
                        if (keys.hasMoreElements())
                            value += " ";
                    }

                    else
                    {
                        to.addAttribute(key, from.getAttribute(key));
                    }
                }
                if (value.length() > 0)
                {
                    to.addAttribute(HTML.Attribute.STYLE, value);
                }
            }
            return to;
        }

        @Override
        protected void closeOutUnwantedEmbeddedTags(AttributeSet attr) throws IOException
        {
            tagsToRemove.removeAllElements();
            // translate css attributes to html
            attr = convertToHTML(attr, null);
            HTML.Tag t;
            Object tValue;
            int firstIndex = -1;
            int size = tags.size();
            // First, find all the tags that need to be removed.
            for (int i = size - 1; i >= 0; i--)
            {
                t = (HTML.Tag) tags.elementAt(i);
                tValue = tagValues.elementAt(i);
                if ((attr == null) || noMatchForTagInAttributes(attr, t, tValue))
                {
                    firstIndex = i;
                    tagsToRemove.addElement(t);
                }
            }
            if (firstIndex != -1)
            {
                // Then close them out.
                boolean removeAll = ((size - firstIndex) == tagsToRemove.size());
                for (int i = size - 1; i >= firstIndex; i--)
                {
                    t = (HTML.Tag) tags.elementAt(i);
                    if (removeAll || tagsToRemove.contains(t))
                    {
                        tags.removeElementAt(i);
                        tagValues.removeElementAt(i);
                    }
                    write('<');
                    write('/');
                    write(t.toString());
                    write('>');
                }
                // Have to output any tags after firstIndex that still remaing,
                // as we closed them out, but they should remain open.
                size = tags.size();
                for (int i = firstIndex; i < size; i++)
                {
                    t = (HTML.Tag) tags.elementAt(i);
                    write('<');
                    write(t.toString());
                    Object o = tagValues.elementAt(i);
                    if (o != null && o instanceof AttributeSet)
                    {
                        writeAttributes((AttributeSet) o);
                    }
                    write('>');
                }
            }
        }

        private boolean noMatchForTagInAttributes(AttributeSet attr, HTML.Tag t, Object tagValue)
        {
            if (attr != null && attr.isDefined(t))
            {
                Object newValue = attr.getAttribute(t);
                if ((tagValue == null) ? (newValue == null) : (newValue != null && tagValue.equals(newValue)))
                {
                    return false;
                }
            }
            return true;
        }

        @Override
        protected void writeEmbeddedTags(AttributeSet attr) throws IOException
        {
            // translate css attributes to html
            attr = convertToHTML(attr, oConvAttr);
            Enumeration names = attr.getAttributeNames();
            while (names.hasMoreElements())
            {
                Object name = names.nextElement();
                if (name instanceof HTML.Tag)
                {
                    HTML.Tag tag = (HTML.Tag) name;
                    if (tag == HTML.Tag.FORM || tags.contains(tag))
                    {
                        continue;
                    }
                    write('<');
                    write(tag.toString());
                    Object o = attr.getAttribute(tag);
                    if (o != null && o instanceof AttributeSet)
                    {
                        writeAttributes((AttributeSet) o);
                    }
                    write('>');
                    tags.addElement(tag);
                    tagValues.addElement(o);
                }
            }
        }

        @Override
        protected void writeAttributes(AttributeSet attr) throws IOException
        {
            convAttr.removeAttributes(convAttr);
            convertToHTML(attr, convAttr);
            Enumeration names = convAttr.getAttributeNames();
            while (names.hasMoreElements())
            {
                Object name = names.nextElement();
                if (name instanceof HTML.Tag || name instanceof StyleConstants || name == HTML.Attribute.ENDTAG)
                {
                    continue;
                }
                write(" " + name + "=\"" + convAttr.getAttribute(name) + "\"");
            }
        }
    }

并且需要重写HTMLEditorKit类方法write如下:

    public void write(Writer out, Document doc, int pos, int len) throws IOException, BadLocationException
        {
            if (doc instanceof HTMLDocument)
            {
                FixedHTMLWriter w = new FixedHTMLWriter(out, (HTMLDocument) doc, pos, len);
                w.write();
            }
            else if (doc instanceof StyledDocument)
            {
                MinimalHTMLWriter w = new MinimalHTMLWriter(out, (StyledDocument) doc, pos, len);
                w.write();
            }
            else
            {
                super.write(out, doc, pos, len);
            }
        }

并通过调用 setEditorKitJEditorPane 上设置覆盖的 HTMLEditorKit

关于java - JEdi​​torPane 正在删除 CSS 字体样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5939732/

相关文章:

html - 在图像卡片上实现叠加悬停时出现问题

html - Bootstrap 面板内的 ScrollView

java - 克隆如何比对象创建具有更高的性能

java - 类型删除和重写泛型方法

java - 有没有办法让 Java 应用程序获得 root 权限?

html - 背景图像高度和宽度在 IE11 上不起作用

Javascript:向表单输入数据时,提交按钮未激活

java - 不断检查 boolean 值

javascript - 通过点击按钮显示不同的表格

html - 将图片与登录字段重叠 - 不响应