JEditorPane 中的 HTMLEditorKit 和自定义标签

问题描述 投票:0回答:3

我使用说明添加自己的标签http://java-sl.com/custom_tag_html_kit.html

class MyParserDelegator extends ParserDelegator {
public MyParserDelegator() {
    try {
        Field f=javax.swing.text.html.parser.ParserDelegator.class.getDeclaredField("dtd");
        f.setAccessible(true);
        DTD dtd=(DTD)f.get(null);
        javax.swing.text.html.parser.Element div=dtd.getElement("div");
        dtd.defineElement("button", div.getType(), true, true,div.getContent(),null, null,div.getAttributes());

    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
    }
}

}

不幸的是它无法正常工作:
image
有人可以帮助我吗?

java swing dtd jeditorpane htmleditorkit
3个回答
1
投票

它适用于我使用以下(jdk 1.7):

Field f = javax.swing.text.html.parser.ParserDelegator.class.getDeclaredField("DTD_KEY");

唯一的变化是按键:

"DTD_KEY"
大写!!

我使用

找到了密钥“DTD_KEY”
Field[] flds = javax.swing.text.html.parser.ParserDelegator.class.getDeclaredFields();
for (Field f: flds)  
{
       System.err.println(f.getName());
}

0
投票

我查看了 JDK 7 的来源:

DTD
不再存储在
dtd
的属性
javax.swing.text.html.parser.ParserDelegator
中,而是存储在
sun.awt.AppContext
中。 来自 sun 包的 AppContext 不应该被 JRE 本身之外的类访问。 因此,使用
javax.swing.text.html.parser.ParserDelegator
的源代码,我编写了
MyParserDelegator
来自行加载 DTD。之后,可以轻松地在 DTD 中添加自定义标签。

下面的代码还包含来自 http://java-sl.com/custom_tag_html_kit.html 的其他类以获得工作示例。

import java.awt.Component;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.ComponentView;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTMLEditorKit.Parser;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.StyleSheet;
import javax.swing.text.html.parser.DTD;
import javax.swing.text.html.parser.DocumentParser;
import javax.swing.text.html.parser.ParserDelegator;

public class CustomTag {
    public static String htmlText = "<html>\n" + "<body>\n" + "<p>\n" + "Text before button\n" + "<button>Text for &lt;button&gt; tag</button>\n"
            + "Text after button\n" + "</p>\n" + "</body>\n" + "</html>";
    JEditorPane edit = new JEditorPane();

    public CustomTag() {
        JFrame frame = new JFrame("Custom tag in HTMLEditorKit");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new JScrollPane(edit));

        edit.setEditorKit(new MyHTMLEditorKit());
        edit.setText(htmlText);

        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) throws Exception {
        new CustomTag();
    }

}

class MyHTMLEditorKit extends HTMLEditorKit {

    public MyHTMLEditorKit() {
        super();
    }

    @Override
    public Document createDefaultDocument() {
        StyleSheet styles = getStyleSheet();
        StyleSheet ss = new StyleSheet();

        ss.addStyleSheet(styles);

        MyHTMLDocument doc = new MyHTMLDocument(ss);
        doc.setParser(getParser());
        doc.setAsynchronousLoadPriority(4);
        doc.setTokenThreshold(100);
        return doc;
    }

    @Override
    public ViewFactory getViewFactory() {
        return new MyHTMLFactory();
    }

    Parser defaultParser;

    @Override
    protected Parser getParser() {
        if (defaultParser == null) {
            defaultParser = new MyParserDelegator();
        }
        return defaultParser;
    }

    class MyHTMLFactory extends HTMLFactory implements ViewFactory {
        public MyHTMLFactory() {
            super();
        }

        @Override
        public View create(Element element) {
            HTML.Tag kind = (HTML.Tag) (element.getAttributes().getAttribute(javax.swing.text.StyleConstants.NameAttribute));

            if (kind instanceof HTML.UnknownTag && element.getName().equals("button")) {

                return new ComponentView(element) {
                    @Override
                    protected Component createComponent() {
                        JButton button = new JButton("Button : text unknown");

                        try {
                            int start = getElement().getStartOffset();
                            int end = getElement().getEndOffset();
                            String text = getElement().getDocument().getText(start, end - start);
                            button.setText(text);
                        } catch (BadLocationException e) {
                            e.printStackTrace();
                        }

                        return button;
                    }
                };

            }
            return super.create(element);
        }
    }
}

class MyHTMLDocument extends HTMLDocument {
    public MyHTMLDocument(StyleSheet styles) {
        super(styles);
    }

    @Override
    public HTMLEditorKit.ParserCallback getReader(int pos) {
        Object desc = getProperty(Document.StreamDescriptionProperty);
        if (desc instanceof URL) {
            setBase((URL) desc);
        }
        return new MyHTMLReader(pos);
    }

    class MyHTMLReader extends HTMLDocument.HTMLReader {
        public MyHTMLReader(int offset) {
            super(offset);
        }

        @Override
        public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
            if (t.toString().equals("button")) {
                registerTag(t, new BlockAction());
            }
            super.handleStartTag(t, a, pos);
        }
    }
}

class MyParserDelegator extends Parser {
    private DTD _dtd;

    public MyParserDelegator() {
        String nm = "html32";
        try {
            _dtd = DTD.getDTD(nm);
            createDTD(_dtd, nm);

            javax.swing.text.html.parser.Element div = _dtd.getElement("div");
            _dtd.defineElement("button", div.getType(), true, true, div.getContent(), null, null, div.getAttributes());
        } catch (IOException e) {
            // (PENDING) UGLY!
            System.out.println("Throw an exception: could not get default dtd: " + nm);
        }
    }

    protected static DTD createDTD(DTD dtd, String name) {
        InputStream in = null;
        try {
            String path = name + ".bdtd";
            in = ParserDelegator.class.getResourceAsStream(path);
            if (in != null) {
                dtd.read(new DataInputStream(new BufferedInputStream(in)));
                DTD.putDTDHash(name, dtd);
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return dtd;
    }

    @Override
    public void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) throws IOException {
        new DocumentParser(_dtd).parse(r, cb, ignoreCharSet);
    }
}

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.