Htmleditorkit And Custom Tags In The Jeditorpane
I use the instructions to add my own tag http://java-sl.com/custom_tag_html_kit.html class MyParserDelegator extends ParserDelegator { public MyParserDelegator() { try {
Solution 1:
It works for me using the following (jdk 1.7):
Field f = javax.swing.text.html.parser.ParserDelegator.class.getDeclaredField("DTD_KEY");
The only change is the key: "DTD_KEY"
upper case!!
I found the key "DTD_KEY" using
Field[] flds = javax.swing.text.html.parser.ParserDelegator.class.getDeclaredFields();
for (Field f: flds)
{
System.err.println(f.getName());
}
Solution 2:
I looked at the sources of JDK 7: the DTD
is no more store in an attribute dtd
of javax.swing.text.html.parser.ParserDelegator
but in sun.awt.AppContext
. Coming from a sun package, AppContext should not be accessed by classes out of the JRE himself.
So using the sources of javax.swing.text.html.parser.ParserDelegator
, I wrote MyParserDelegator
that load the DTD himself. After that, the custom tag can be added in DTD easily.
The code below also contains the other classes from http://java-sl.com/custom_tag_html_kit.html to get a working example.
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;
publicclassCustomTag {
publicstaticStringhtmlText="<html>\n" + "<body>\n" + "<p>\n" + "Text before button\n" + "<button>Text for <button> tag</button>\n"
+ "Text after button\n" + "</p>\n" + "</body>\n" + "</html>";
JEditorPaneedit=newJEditorPane();
publicCustomTag() {
JFrameframe=newJFrame("Custom tag in HTMLEditorKit");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(newJScrollPane(edit));
edit.setEditorKit(newMyHTMLEditorKit());
edit.setText(htmlText);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
publicstaticvoidmain(String[] args)throws Exception {
newCustomTag();
}
}
classMyHTMLEditorKitextendsHTMLEditorKit {
publicMyHTMLEditorKit() {
super();
}
@Overridepublic Document createDefaultDocument() {
StyleSheetstyles= getStyleSheet();
StyleSheetss=newStyleSheet();
ss.addStyleSheet(styles);
MyHTMLDocumentdoc=newMyHTMLDocument(ss);
doc.setParser(getParser());
doc.setAsynchronousLoadPriority(4);
doc.setTokenThreshold(100);
return doc;
}
@Overridepublic ViewFactory getViewFactory() {
returnnewMyHTMLFactory();
}
Parser defaultParser;
@Overrideprotected Parser getParser() {
if (defaultParser == null) {
defaultParser = newMyParserDelegator();
}
return defaultParser;
}
classMyHTMLFactoryextendsHTMLFactoryimplementsViewFactory {
publicMyHTMLFactory() {
super();
}
@Overridepublic View create(Element element) {
HTML.Tagkind= (HTML.Tag) (element.getAttributes().getAttribute(javax.swing.text.StyleConstants.NameAttribute));
if (kind instanceof HTML.UnknownTag && element.getName().equals("button")) {
returnnewComponentView(element) {
@Overrideprotected Component createComponent() {
JButtonbutton=newJButton("Button : text unknown");
try {
intstart= getElement().getStartOffset();
intend= getElement().getEndOffset();
Stringtext= getElement().getDocument().getText(start, end - start);
button.setText(text);
} catch (BadLocationException e) {
e.printStackTrace();
}
return button;
}
};
}
returnsuper.create(element);
}
}
}
classMyHTMLDocumentextendsHTMLDocument {
publicMyHTMLDocument(StyleSheet styles) {
super(styles);
}
@Overridepublic HTMLEditorKit.ParserCallback getReader(int pos) {
Objectdesc= getProperty(Document.StreamDescriptionProperty);
if (desc instanceof URL) {
setBase((URL) desc);
}
returnnewMyHTMLReader(pos);
}
classMyHTMLReaderextendsHTMLDocument.HTMLReader {
publicMyHTMLReader(int offset) {
super(offset);
}
@OverridepublicvoidhandleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
if (t.toString().equals("button")) {
registerTag(t, newBlockAction());
}
super.handleStartTag(t, a, pos);
}
}
}
classMyParserDelegatorextendsParser {
private DTD _dtd;
publicMyParserDelegator() {
Stringnm="html32";
try {
_dtd = DTD.getDTD(nm);
createDTD(_dtd, nm);
javax.swing.text.html.parser.Elementdiv= _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);
}
}
protectedstatic DTD createDTD(DTD dtd, String name) {
InputStreamin=null;
try {
Stringpath= name + ".bdtd";
in = ParserDelegator.class.getResourceAsStream(path);
if (in != null) {
dtd.read(newDataInputStream(newBufferedInputStream(in)));
DTD.putDTDHash(name, dtd);
}
} catch (Exception e) {
System.out.println(e);
}
return dtd;
}
@Overridepublicvoidparse(Reader r, ParserCallback cb, boolean ignoreCharSet)throws IOException {
newDocumentParser(_dtd).parse(r, cb, ignoreCharSet);
}
}
Post a Comment for "Htmleditorkit And Custom Tags In The Jeditorpane"