【问题标题】:How can I change the color of a particular element of a HTMLDocument in a JEditorPane?如何更改 JEditorPane 中 HTMLDocument 的特定元素的颜色?
【发布时间】:2009-03-12 04:40:29
【问题描述】:

当我将鼠标悬停在链接上时,我基本上想实现更改链接的颜色。当我将鼠标悬停在链接上时触发的 HyperlinkEvent 将 HTML 元素交给我,但它不会让我在其上设置任何样式属性,而且我不知道如何获取具有可设置属性的元素。

【问题讨论】:

    标签: java jeditorpane dom


    【解决方案1】:

    我想出了使用样式文档和 HTMLEditorKit 的一些帮助我想做什么:

    public class HighlightHyperlinkExample {
        private static Element lastHyperlinkElementEntered;
        private static JEditorPane textPane;
    
    
        public static void main(String[] args) {
            textPane = new JEditorPane();
            textPane.setContentType(new HTMLEditorKit().getContentType());
            JScrollPane scrollPane = new JScrollPane(textPane);
            textPane.setText(
                    "Sample text with <a href=\"x\">a link</a> and another <a href=\"x\">link</a>.");
    
            initListeners();
    
            JFrame frame = new JFrame();
            frame.add(scrollPane);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    
    
        private static void initListeners() {
            textPane.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseExited(MouseEvent e) {
                    removeHyperlinkHighlight();
                }
            });
            textPane.addMouseMotionListener(new MouseMotionListener() {
                public void mouseDragged(MouseEvent e) {
                }
    
                public void mouseMoved(MouseEvent e) {
                    Point pt = new Point(e.getX(), e.getY());
                    int pos = textPane.viewToModel(pt);
                    if (pos >= 0) {
                        HTMLDocument hdoc = (HTMLDocument) textPane.getDocument();
                        Element elem = hdoc.getCharacterElement(pos);
                        if (elem != null) {
                            AttributeSet a = elem.getAttributes();
                            AttributeSet anchor = (AttributeSet) a.getAttribute(HTML.Tag.A);
                            if (anchor != null) {
                                //only highlight anchor tags
                                highlightHyperlink(elem);
                            } else {
                                removeHyperlinkHighlight();
                            }
                        }
                    }
                }
            });
        }
    
        private static void removeHyperlinkHighlight() {
            changeColor(lastHyperlinkElementEntered, Color.BLUE);
            lastHyperlinkElementEntered = null;
        }
    
        private static void highlightHyperlink(Element hyperlinkElement) {
            if (hyperlinkElement != lastHyperlinkElementEntered) {
                lastHyperlinkElementEntered = hyperlinkElement;
                changeColor(hyperlinkElement, Color.RED);
            }
        }
    
        private static void changeColor(Element el, Color color) {
            if (lastHyperlinkElementEntered != null) {
                HTMLDocument doc = (HTMLDocument) textPane.getDocument();
                int start = el.getStartOffset();
                int end = el.getEndOffset();
                StyleContext ss = doc.getStyleSheet();
                Style style = ss.addStyle("HighlightedHyperlink", null);
                style.addAttribute(StyleConstants.Foreground, color);
                doc.setCharacterAttributes(start, end - start, style, false);
            }
        }
    }
    

    【讨论】:

    • 考虑记住在#highlightHyperlink 中被覆盖的实际颜色,并在#removeHyperlinkHighlight 中使用记住的颜色。
    • 这个例子会更好。
    【解决方案2】:

    Highlighting Words in a JTextComponent

    JTextArea textComp = new JTextArea();
    
    // Highlight the occurrences of the word "public"
    highlight(textComp, "public");
    
    // Creates highlights around all occurrences of pattern in textComp
    public void highlight(JTextComponent textComp, String pattern) {
        // First remove all old highlights
        removeHighlights(textComp);
    
        try {
            Highlighter hilite = textComp.getHighlighter();
            Document doc = textComp.getDocument();
            String text = doc.getText(0, doc.getLength());
            int pos = 0;
    
            // Search for pattern
            while ((pos = text.indexOf(pattern, pos)) >= 0) {
                // Create highlighter using private painter and apply around pattern
                hilite.addHighlight(pos, pos+pattern.length(), myHighlightPainter);
                pos += pattern.length();
            }
        } catch (BadLocationException e) {
        }
    }
    
    // Removes only our private highlights
    public void removeHighlights(JTextComponent textComp) {
        Highlighter hilite = textComp.getHighlighter();
        Highlighter.Highlight[] hilites = hilite.getHighlights();
    
        for (int i=0; i<hilites.length; i++) {
            if (hilites[i].getPainter() instanceof MyHighlightPainter) {
                hilite.removeHighlight(hilites[i]);
            }
        }
    }
    
    // An instance of the private subclass of the default highlight painter
    Highlighter.HighlightPainter myHighlightPainter = new MyHighlightPainter(Color.red);
    
    // A private subclass of the default highlight painter
    class MyHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter {
        public MyHighlightPainter(Color color) {
            super(color);
        }
    }
    

    【讨论】:

    • 谢谢。我完全忘记了荧光笔。不幸的是,我想做的是改变前景,而不是背景,这对于荧光笔来说要困难得多。然而,它确实让我走上了正确的道路。所以,谢谢。
    • 只是想说,当我打开您的链接 [Highlighting Words in a JTextComponent] 时,它会链接到带有病毒的页面。
    猜你喜欢
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    相关资源
    最近更新 更多