【问题标题】:HTMLEditorKit and Custom tags in the JEditorPaneJEdi​​torPane 中的 HTMLEditorKit 和自定义标签
【发布时间】:2012-03-11 20:24:21
【问题描述】:

我使用说明添加我自己的标签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) {
    }
}

}

不幸的是,它无法正常工作:

谁能帮帮我?

【问题讨论】:

    标签: java swing dtd jeditorpane htmleditorkit


    【解决方案1】:

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

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

    唯一变化的是key:"DTD_KEY"大写!!

    我使用

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

    【讨论】:

      【解决方案2】:

      我查看了 JDK 7 的源代码:DTD 不再存储在 javax.swing.text.html.parser.ParserDelegator 的属性 dtd 中,而是在 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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-24
        • 1970-01-01
        • 1970-01-01
        • 2012-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-11
        相关资源
        最近更新 更多