开发者

JEditorPane is removing CSS font styles

I am trying to get the JEditorPane to preserve any CSS font style. Unfortunately, it seems to be stripping it out altogether for paragraph tags (and other tags as well) and converting it to a font tag for the A tags.

Consider the following example:

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);
     开发者_JAVA百科   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);
    }
}

This produces the following output for the p and a tags:

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

and

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

As you can see, it preserves the padding and margin styles but strips out the font style for the paragraph tag and converts it to a font tag for the A tag.

Before getText is called, if you display it it will actually style the paragraph correctly.

How do I get it so that it will preserve the font attribute as is?


Ok,

Figured out the issue is definitely in the HTMLWriter class. Unfortunately, they did not make it easy to override this class, but I beleive I have it.

    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) + "\"");
            }
        }
    }

And you need to override the HTMLEditorKit class method write as follows:

    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);
            }
        }

And set the overridden HTMLEditorKit on the JEditorPane using a call to setEditorKit.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜