Package javax.swing.text.html

Source Code of javax.swing.text.html.HTMLEditorKit$LinkHighlightPainter

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Vadim L. Bogdanov, Alexander T. Simbirtsev
* @version $Revision$
*/
package javax.swing.text.html;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.Element;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.Position;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.Position.Bias;
import javax.swing.text.html.parser.ParserDelegator;

import org.apache.harmony.awt.text.TextUtils;
import org.apache.harmony.x.swing.StringConstants;

import org.apache.harmony.x.swing.internal.nls.Messages;

public class HTMLEditorKit extends StyledEditorKit implements Accessible {
    public static class HTMLFactory implements ViewFactory {

        public View create(final Element elem) {
            HTML.Tag tag = getHTMLTagByElement(elem);

            if (HTML.Tag.CONTENT.equals(tag)) {
                return new InlineView(elem);

            } else if (HTML.Tag.IMPLIED.equals(tag)
                    || HTML.Tag.P.equals(tag)
                    || HTML.Tag.H1.equals(tag)
                    || HTML.Tag.H2.equals(tag)
                    || HTML.Tag.H3.equals(tag)
                    || HTML.Tag.H4.equals(tag)
                    || HTML.Tag.H5.equals(tag)
                    || HTML.Tag.H6.equals(tag)
                    || HTML.Tag.DT.equals(tag)
                    ) {
                return new ParagraphView(elem);

            } else if (HTML.Tag.MENU.equals(tag)
                    || HTML.Tag.DIR.equals(tag)
                    || HTML.Tag.UL.equals(tag)
                    || HTML.Tag.OL.equals(tag)) {
                return new ListView(elem);

            } else if (HTML.Tag.LI.equals(tag)
                    || HTML.Tag.DL.equals(tag)
                    || HTML.Tag.DD.equals(tag)
                    || HTML.Tag.BODY.equals(tag)
                    || HTML.Tag.HTML.equals(tag)
                    || HTML.Tag.CENTER.equals(tag)
                    || HTML.Tag.DIV.equals(tag)
                    || HTML.Tag.BLOCKQUOTE.equals(tag)
                    || HTML.Tag.PRE.equals(tag)) {
                return new BlockView(elem, View.Y_AXIS);

            } else if (HTML.Tag.IMG.equals(tag)) {
                return new ImageView(elem);

            } else if (HTML.Tag.HR.equals(tag)) {
                return new HRuleTagView(elem);

            } else if (HTML.Tag.BR.equals(tag)) {
                return new BRView(elem);

            } else if (HTML.Tag.TABLE.equals(tag)) {
                return new TableTagView(elem);

            } else if (HTML.Tag.FORM.equals(tag)) {
                return new BlockView(elem, View.X_AXIS);

            } else if (HTML.Tag.INPUT.equals(tag)) {
                return new FormView(elem);

            } else if (HTML.Tag.SELECT.equals(tag)
                    || HTML.Tag.TEXTAREA.equals(tag)) {
                return new FormView(elem);

            } else if (HTML.Tag.OBJECT.equals(tag)) {
                return new ObjectView(elem);

            } else if (HTML.Tag.FRAMESET.equals(tag)) {
                return new FrameSetTagView(elem);

            } else if (HTML.Tag.FRAME.equals(tag)) {
                return new FrameTagView(elem);

            } else if (HTML.Tag.NOFRAMES.equals(tag)) {
                return new NoFramesTagView(elem);

            } else if (HTML.Tag.HEAD.equals(tag)) {
                return new HeadTagView(elem);
            }

            // TODO: uncomment the next line and remove throw
            // when all tags are supported
//            return new LabelView(elem);
            throw new UnsupportedOperationException(Messages.getString("swing.9F") + tag); //$NON-NLS-1$
        }
    }

    public abstract static class HTMLTextAction extends StyledTextAction {
        public HTMLTextAction(final String name) {
            super(name);
        }

        protected int elementCountToTag(final HTMLDocument doc,
                                        final int offset,
                                        final HTML.Tag tag) {
            int count = -1;
            Element e;
            for (e = doc.getCharacterElement(offset);
                 e != null && !tag.equals(getHTMLTagByElement(e));
                 e = e.getParentElement()) {
                count++;
            }
            if (e == null) {
                return -1;
            }
            return count;
        }

        protected Element findElementMatchingTag(final HTMLDocument doc,
                                                 final int offset,
                                                 final HTML.Tag tag) {
            Element e = doc.getCharacterElement(offset);
            while (e != null && !tag.equals(getHTMLTagByElement(e))) {
                e = e.getParentElement();
            }
            return e;
        }

        protected Element[] getElementsAt(final HTMLDocument doc,
                                          final int offset) {
            ArrayList list = new ArrayList();
            Element e = doc.getDefaultRootElement();
            while (true) {
                list.add(e);
                if (e.getElementCount() == 0) {
                    break;
                }
                e = e.getElement(e.getElementIndex(offset));
            }

            return (Element[])list.toArray(new Element[list.size()]);
        }

        protected HTMLDocument getHTMLDocument(final JEditorPane pane) {
            Document doc = pane.getDocument();
            if (doc instanceof HTMLDocument) {
                return (HTMLDocument)doc;
            }
            throw new IllegalArgumentException(Messages.getString("swing.A0")); //$NON-NLS-1$
        }

        protected HTMLEditorKit getHTMLEditorKit(final JEditorPane pane) {
            EditorKit editorKit = pane.getEditorKit();
            if (editorKit instanceof HTMLEditorKit) {
                return (HTMLEditorKit)editorKit;
            }
            throw new IllegalArgumentException(Messages.getString("swing.A1")); //$NON-NLS-1$
        }
    }

    public static class InsertHTMLTextAction extends HTMLTextAction {
        protected HTML.Tag addTag;
        protected HTML.Tag alternateAddTag;
        protected HTML.Tag alternateParentTag;
        protected String html;
        protected HTML.Tag parentTag;

        public InsertHTMLTextAction(final String name, final String html,
                                    final HTML.Tag parentTag,
                                    final HTML.Tag addTag,
                                    final HTML.Tag alternateParentTag,
                                    final HTML.Tag alternateAddTag) {
            super(name);
            this.html = html;
            this.parentTag = parentTag;
            this.addTag = addTag;
            this.alternateParentTag = alternateParentTag;
            this.alternateAddTag = alternateAddTag;
        }

        public InsertHTMLTextAction(final String name, final String html,
                                    final HTML.Tag parentTag,
                                    final HTML.Tag addTag) {
            super(name);
            this.html = html;
            this.parentTag = parentTag;
            this.addTag = addTag;
        }

        public void actionPerformed(final ActionEvent event) {
            if (event == null) {
                return;
            }

            JEditorPane editor = getEditor(event);
            HTMLDocument doc = getHTMLDocument(editor);
            int offset = editor.getCaretPosition();

            HTML.Tag usedParentTag = parentTag;
            HTML.Tag usedAddTag = addTag;
            int popDepth = elementCountToTag(doc, offset, parentTag);
            if (popDepth == -1 && alternateParentTag != null) {
                usedParentTag = alternateParentTag;
                usedAddTag = alternateAddTag;
                popDepth = elementCountToTag(doc, offset, alternateParentTag);
            }
            if (popDepth == -1) {
                return;
            }

            Element insertElement = findElementMatchingTag(doc, offset,
                                                           usedParentTag);
            if (insertElement.getStartOffset() == offset) {
                insertAtBoundary(editor, doc, offset, insertElement, html,
                                 usedParentTag, usedAddTag);
            } else {
                int pushDepth = 0;
                insertHTML(editor, doc, offset, html,
                           popDepth, pushDepth, usedAddTag);
            }
        }

        protected void insertHTML(final JEditorPane editor,
                                  final HTMLDocument doc, final int offset,
                                  final String html, final int popDepth,
                                  final int pushDepth, final HTML.Tag addTag) {
            HTMLEditorKit editorKit = getHTMLEditorKit(editor);
            try {
                editorKit.insertHTML(doc, offset, html,
                                     popDepth, pushDepth, addTag);
            } catch (BadLocationException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        protected void insertAtBoundary(final JEditorPane editor,
                                        final HTMLDocument doc,
                                        final int offset,
                                        final Element insertElement,
                                        final String html,
                                        final HTML.Tag parentTag,
                                        final HTML.Tag addTag) {
            insertAtBoundaryImpl(editor, doc, offset, insertElement, html,
                                 parentTag, addTag);
        }

        /**
         * @deprecated
         */
        protected void insertAtBoundry(final JEditorPane editor,
                                       final HTMLDocument doc,
                                       final int offset,
                                       final Element insertElement,
                                       final String html,
                                       final HTML.Tag parentTag,
                                       final HTML.Tag addTag) {
            insertAtBoundaryImpl(editor, doc, offset, insertElement, html,
                                 parentTag, addTag);
        }

        private void insertAtBoundaryImpl(final JEditorPane editor,
                                          final HTMLDocument doc,
                                          final int offset,
                                          final Element insertElement,
                                          final String html,
                                          final HTML.Tag parentTag,
                                          final HTML.Tag addTag) {
            int popDepth = elementCountToTag(doc, offset, parentTag) + 1;
            int pushDepth = 1;
            insertHTML(editor, doc, offset, html, popDepth, pushDepth, addTag);
        }
    }

    public static class LinkController extends MouseAdapter
            implements MouseMotionListener, Serializable {

        private Element prevLinkUnderMouse;

        public void mouseClicked(final MouseEvent e) {
            JEditorPane pane = (JEditorPane)e.getSource();
            if (pane.isEditable()) {
                return;
            }

            int pos = pane.viewToModel(e.getPoint());
            activateLink(pos, pane);
        }

        public void mouseDragged(final MouseEvent e) {
            // does nothing
        }

        public void mouseMoved(final MouseEvent e) {
            JEditorPane pane = (JEditorPane)e.getSource();
            Element linkElement = getLinkElement(pane, e.getPoint());
            updateMouseCursor(e, linkElement);

            if (pane.isEditable()) {
                return;
            }

            fireHyperlinkEvent(e, linkElement);
        }

        protected void activateLink(final int pos, final JEditorPane editor) {
            Element elem = HTMLEditorKit.getLinkElement(editor, pos);
            if (elem != null) {
                HTMLEditorKit.fireHyperlinkEvent(editor,
                        HyperlinkEvent.EventType.ACTIVATED, elem);
            }
        }

        private void updateMouseCursor(final MouseEvent e,
                                       final Element linkElement) {
            JEditorPane pane = (JEditorPane)e.getSource();
            HTMLEditorKit editorKit = (HTMLEditorKit)pane.getEditorKit();
            if (!pane.isEditable() && linkElement != null) {
                e.getComponent().setCursor(editorKit.getLinkCursor());
            } else {
                e.getComponent().setCursor(editorKit.getDefaultCursor());
            }
        }

        private void fireHyperlinkEvent(final MouseEvent e,
                                        final Element linkElement) {
            if (prevLinkUnderMouse == linkElement) {
                return;
            }

            JEditorPane pane = (JEditorPane)e.getSource();
            if (prevLinkUnderMouse != null) {
                HTMLEditorKit.fireHyperlinkEvent(pane,
                        HyperlinkEvent.EventType.EXITED, prevLinkUnderMouse);
            }
            if (linkElement != null) {
                HTMLEditorKit.fireHyperlinkEvent(pane,
                        HyperlinkEvent.EventType.ENTERED, linkElement);
            }
            prevLinkUnderMouse = linkElement;
        }

        private Element getLinkElement(final JEditorPane pane, final Point p) {
            return HTMLEditorKit.getLinkElement(pane, pane.viewToModel(p));
        }
    }

    public abstract static class Parser {
        public abstract void parse(final Reader r, final ParserCallback cb,
                                   final boolean ignoreCharSet)
                throws IOException;
    }

    public static class ParserCallback {
        public static final Object IMPLIED = "_implied_";

        public void flush() throws BadLocationException {
        }

        public void handleComment(final char[] data, final int pos) {
        }

        public void handleEndOfLineString(final String eol) {
        }

        public void handleEndTag(final HTML.Tag tag, final int pos) {
        }

        public void handleError(final String errorMsg, final int pos) {
        }

        public void handleSimpleTag(final HTML.Tag tag,
                                    final MutableAttributeSet attr,
                                    final int pos) {
        }

        public void handleStartTag(final HTML.Tag tag,
                                   final MutableAttributeSet attr,
                                   final int pos) {
        }

        public void handleText(final char[] data, final int pos) {
        }
    }

    private static class NavigateLinkAction extends HTMLTextAction {
        private static final HashMap highlightTags = new HashMap();

        public NavigateLinkAction(final String name) {
            super(name);
        }

        public void actionPerformed(final ActionEvent e) {
            if (getEditor(e).isEditable()) {
                return;
            }

            JEditorPane editor = getEditor(e);
            Caret caret = editor.getCaret();
            HTMLDocument doc = getHTMLDocument(editor);

            Element link = getNextLinkElement(doc, caret.getDot(), isForward());
            if (link != null) {
                moveHighlight(editor,
                              link.getStartOffset(), link.getEndOffset());
            }
        }

        private boolean isForward() {
            return "next-link-action".equals(getValue(NAME));
        }

        private static Element getNextLinkElement(final HTMLDocument doc,
                                                  final int pos,
                                                  final boolean forward) {
            HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);
            int linkPos = -1;
            for (; it.isValid(); it.next()) {
                if (forward) {
                    if (it.getStartOffset() > pos) {
                        linkPos = it.getStartOffset();
                        break;
                    }
                } else {
                    if (it.getStartOffset() >= pos) {
                        break;
                    }
                    linkPos = it.getStartOffset();
                }
            }

            return linkPos != -1 ? doc.getCharacterElement(linkPos) : null;
        }

        private static void moveHighlight(final JEditorPane editor,
                                          final int start, final int end) {
            Highlighter highlighter = editor.getHighlighter();
            Object tag = highlightTags.get(highlighter);
            if (tag != null) {
                highlighter.removeHighlight(tag);
                highlightTags.remove(highlighter);
            }
            try {
                tag = highlighter.addHighlight(start, end,
                                               new LinkHighlightPainter());
                highlightTags.put(highlighter, tag);
                editor.getCaret().setDot(start);
            } catch (final BadLocationException e) {
            }
        }

        static void removeHighlight(final JEditorPane editor) {
            Highlighter highlighter = editor.getHighlighter();
            Object tag = highlightTags.get(highlighter);
            if (tag != null) {
                highlighter.removeHighlight(tag);
                highlightTags.remove(highlighter);
            }
        }
    }

    private static class ActivateLinkAction extends HTMLTextAction {
        public ActivateLinkAction() {
            super("activate-link-action");
        }

        public void actionPerformed(final ActionEvent e) {
            JEditorPane editor = getEditor(e);
            if (!editor.isEditable()) {
                activateLink(editor.getCaretPosition(), editor);
            }
        }
    }

    private static class LinkHighlightPainter
            extends DefaultHighlighter.DefaultHighlightPainter {
        public LinkHighlightPainter() {
            super(Color.RED);
        }

        public Shape paintLayer(final Graphics g, final int p0, final int p1,
                                final Shape shape, final JTextComponent jtc,
                                final View view) {
            return TextUtils.paintLayer(g, p0, p1, shape,
                                        jtc.getSelectionColor(), view, false);
        }
    }

    private static class HeadTagView extends View {
        public HeadTagView(final Element elem) {
            super(elem);
        }

        public float getPreferredSpan(final int axis) {
            return 0.0f;
        }

        public int viewToModel(final float x, final float y,
                               final Shape a, final Bias[] biasRet) {
            return 0;
        }

        public void paint(final Graphics g, final Shape allocation) {
        }

        public Shape modelToView(final int pos, final Shape a,
                                 final Bias b) throws BadLocationException {
            return new Rectangle(0, 0);
        }

        public int getNextVisualPositionFrom(final int pos, final Bias b,
                final Shape a, final int direction,
                final Bias[] biasRet) throws BadLocationException {
            if (direction != NORTH && direction != SOUTH
                    && direction != EAST && direction != WEST) {
                throw new IllegalArgumentException(Messages.getString("swing.84")); //$NON-NLS-1$
            }
            biasRet[0] = Position.Bias.Forward;
            return getEndOffset();
        }
    }

    public static final String BOLD_ACTION = "html-bold-action";
    public static final String COLOR_ACTION = "html-color-action";
    public static final String FONT_CHANGE_BIGGER = "html-font-bigger";
    public static final String FONT_CHANGE_SMALLER = "html-font-smaller";
    public static final String IMG_ALIGN_BOTTOM = "html-image-align-bottom";
    public static final String IMG_ALIGN_MIDDLE = "html-image-align-middle";
    public static final String IMG_ALIGN_TOP = "html-image-align-top";
    public static final String IMG_BORDER = "html-image-border";
    public static final String ITALIC_ACTION = "html-italic-action";
    public static final String LOGICAL_STYLE_ACTION = "html-logical-style-action";
    public static final String PARA_INDENT_LEFT = "html-para-indent-left";
    public static final String PARA_INDENT_RIGHT = "html-para-indent-right";

    public static final String DEFAULT_CSS = "default.css";

    private static StyleSheet styleSheet;
    private static Parser parser;
    private static ViewFactory viewFactory;
    private static final LinkController linkController = new LinkController();
    private static Action[] actions;

    private Cursor defaultCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
    private Cursor linkCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
    private boolean autoFormSubmission = true;

    public HTMLEditorKit() {
        if (actions == null) {
            createStaticActions();
        }
    }

    public Object clone() {
        return super.clone();
    }

    public Document createDefaultDocument() {
        HTMLDocument document = new HTMLDocument();
        document.getStyleSheet().addStyleSheet(getStyleSheet());
        document.setParser(getParser());
        document.setAsynchronousLoadPriority(4);
        return document;
    }

    public AccessibleContext getAccessibleContext() {
        // TODO: implement
        throw new UnsupportedOperationException(Messages.getString("swing.9F")); //$NON-NLS-1$
    }

    public Action[] getActions() {
        return (Action[])actions.clone();
    }

    public String getContentType() {
        return "text/html";
    }

    public MutableAttributeSet getInputAttributes() {
        return super.getInputAttributes();
    }

    public ViewFactory getViewFactory() {
        if (viewFactory == null) {
            viewFactory = new HTMLFactory();
        }
        return viewFactory;
    }

    public void install(final JEditorPane pane) {
        super.install(pane);

        pane.addMouseListener(linkController);
        pane.addMouseMotionListener(linkController);
    }

    public void deinstall(final JEditorPane pane) {
        pane.removeMouseListener(linkController);
        pane.removeMouseMotionListener(linkController);
        NavigateLinkAction.removeHighlight(pane);

        super.deinstall(pane);
    }

    public void setAutoFormSubmission(final boolean auto) {
        autoFormSubmission = auto;
    }

    public boolean isAutoFormSubmission() {
        return autoFormSubmission;
    }

    public void setDefaultCursor(final Cursor cursor) {
        defaultCursor = cursor;
    }

    public Cursor getDefaultCursor() {
        return defaultCursor;
    }

    public void setLinkCursor(final Cursor cursor) {
        linkCursor = cursor;
    }

    public Cursor getLinkCursor() {
        return linkCursor;
    }

    public void setStyleSheet(final StyleSheet ss) {
        styleSheet = ss;
    }

    public StyleSheet getStyleSheet() {
        if (styleSheet == null) {
            styleSheet = new StyleSheet();
            URL url = HTMLEditorKit.class.getResource(DEFAULT_CSS);
            try {
                styleSheet.loadRules(new BufferedReader(
                    new InputStreamReader(url.openStream())), url);
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }

        return styleSheet;
    }

    public void insertHTML(final HTMLDocument doc, final int offset,
                           final String html, final int popDepth,
                           final int pushDepth, final HTML.Tag insertTag)
            throws BadLocationException, IOException {
        if (offset > doc.getLength()) {
            throw new BadLocationException(Messages.getString("swing.98"), offset); //$NON-NLS-1$
        }

        ParserCallback htmlReader = doc.getReader(offset, popDepth,
                                                  pushDepth, insertTag);
        StringReader in = new StringReader(html);

        getParser().parse(in, htmlReader, false);
        htmlReader.flush();
        in.close();
    }

    public void read(final Reader in, final Document doc, final int pos)
            throws IOException, BadLocationException {
        if (!(doc instanceof HTMLDocument)) {
            super.read(in, doc, pos);
            return;
        }

        HTMLDocument htmlDoc = (HTMLDocument)doc;
        checkReadPosition(htmlDoc, pos);

        ParserCallback htmlReader = htmlDoc.getReader(pos);
        Object property = doc.getProperty(StringConstants
                                          .IGNORE_CHARSET_DIRECTIVE);
        getParser().parse(in, htmlReader, property == null ? false
                          : ((Boolean)property).booleanValue());
        htmlReader.flush();
        in.close();
    }

    public void write(final Writer out, final Document doc, final int pos,
                      final int len) throws IOException, BadLocationException {
        HTMLDocument htmlDoc;
        int fixedPos = pos;

        if (doc instanceof HTMLDocument) {
            htmlDoc = (HTMLDocument)doc;
        } else {
            htmlDoc = (HTMLDocument)createDefaultDocument();
            htmlDoc.insertString(0, doc.getText(pos, len), null);
            fixedPos = 0;
        }

        HTMLWriter writer = new HTMLWriter(out, htmlDoc, fixedPos, len);
        writer.write();
    }

    protected Parser getParser() {
        if (parser == null) {
            parser = new ParserDelegator();
        }

        return parser;
    }

    protected void createInputAttributes(final Element elem,
                                         final MutableAttributeSet set) {
        super.createInputAttributes(elem, set);
    }

    static HTML.Tag getHTMLTagByElement(final Element elem) {
        final Object result = elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
        return (result instanceof HTML.Tag) ? (HTML.Tag)result : null;
    }

    private static String getURLString(final Element e) {
        AttributeSet aSet = (AttributeSet)e.getAttributes()
                .getAttribute(HTML.Tag.A);
        return aSet == null
                ? null
                : (String)aSet.getAttribute(HTML.Attribute.HREF);
    }

    private static void checkReadPosition(final HTMLDocument doc, final int pos)
            throws BadLocationException {
        if (pos < 0) {
            throw new RuntimeException(Messages.getString("swing.A2")); //$NON-NLS-1$
        }
        if (pos > doc.getLength()) {
            throw new BadLocationException(Messages.getString("swing.98"), pos); //$NON-NLS-1$
        }
        if (doc.getLength() != 0) {
            Element body = doc.getElement(doc.getDefaultRootElement(),
                                          StyleConstants.NameAttribute,
                                          HTML.Tag.BODY);
            if (pos < body.getStartOffset() || pos > body.getEndOffset()) {
                throw new RuntimeException(Messages.getString("swing.A3")); //$NON-NLS-1$
            }
        }
    }

    private Action[] createStaticActions() {
        if (actions == null) {
            Action[] htmlActions = getDefaultActions();
            Action[] styledActions = super.getActions();
            actions = new Action[htmlActions.length + styledActions.length];
            System.arraycopy(styledActions, 0, actions, 0, styledActions.length);
            System.arraycopy(htmlActions, 0, actions, styledActions.length,
                             htmlActions.length);
        }
        return actions;
    }

    private Action[] getDefaultActions() {
        return new Action[] {
            new InsertHTMLTextAction("InsertOrderedList", "<ol><li></li></ol>",
                HTML.Tag.BODY, HTML.Tag.OL),
            new InsertHTMLTextAction("InsertOrderedListItem", "<ol><li></li></ol>",
                HTML.Tag.OL, HTML.Tag.LI, HTML.Tag.BODY, HTML.Tag.OL),
            new InsertHTMLTextAction("InsertUnorderedList", "<ul><li></li></ul>",
                HTML.Tag.BODY, HTML.Tag.UL),
            new InsertHTMLTextAction("InsertUnorderedListItem", "<ul><li></li></ul>",
                HTML.Tag.UL, HTML.Tag.LI, HTML.Tag.BODY, HTML.Tag.UL),
            new InsertHTMLTextAction("InsertTable",
                                     "<table border=1><tr><td></td></tr></table>",
                                     HTML.Tag.BODY, HTML.Tag.TABLE),
            new InsertHTMLTextAction("InsertTableDataCell",
                                     "<table border=1><tr><td></td></tr></table>",
                                     HTML.Tag.TR, HTML.Tag.TD,
                                     HTML.Tag.BODY, HTML.Tag.TABLE),
            new InsertHTMLTextAction("InsertTableRow",
                                     "<table border=1><tr><td></td></tr></table>",
                                     HTML.Tag.TABLE, HTML.Tag.TR,
                                     HTML.Tag.BODY, HTML.Tag.TABLE),
            new InsertHTMLTextAction("InsertPre", "<pre></pre>",
                                     HTML.Tag.BODY, HTML.Tag.PRE),
            new InsertHTMLTextAction("InsertHR", "<hr>", HTML.Tag.P, HTML.Tag.HR),
            new NavigateLinkAction("next-link-action"),
            new NavigateLinkAction("previous-link-action"),
            new ActivateLinkAction()
        };
    }

    private static void activateLink(final int pos, final JEditorPane editor) {
        Element elem = getLinkElement(editor, pos);
        if (elem != null) {
            fireHyperlinkEvent(editor, HyperlinkEvent.EventType.ACTIVATED,
                               elem);
        }
    }

    private static void fireHyperlinkEvent(final JEditorPane pane,
                                           final HyperlinkEvent.EventType eventID,
                                           final Element elem) {
        String urlString = getURLString(elem);

        URL base = ((HTMLDocument)pane.getDocument()).getBase();
        HyperlinkEvent event = new HyperlinkEvent(pane, eventID,
                                                  HTML.resolveURL(urlString,
                                                                  base),
                                                  urlString, elem);
        pane.fireHyperlinkUpdate(event);
    }

    private static Element getLinkElement(final JEditorPane pane, final int pos) {
        Element e = (((HTMLDocument)pane.getDocument()).getCharacterElement(pos));
        for (; e != null; e = e.getParentElement()) {
            if (getURLString(e) != null) {
                return e;
            }
        }

        return null;
    }
}
TOP

Related Classes of javax.swing.text.html.HTMLEditorKit$LinkHighlightPainter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.