Как я могу изменить цвет определенного элемента HTMLDocument в JEditorPane? - PullRequest
2 голосов
/ 11 марта 2009

Я хочу реализовать изменение цвета ссылок при наведении на них курсора. HyperlinkEvent, который запускается при наведении мыши на ссылку, передает мне элемент HTML, но он не позволяет мне устанавливать для него какие-либо атрибуты стиля, и я не могу понять, как получить элементы, которые имеют настраиваемые атрибуты.

Ответы [ 2 ]

3 голосов
/ 11 марта 2009

Я понял, что хочу сделать, используя стилизованные документы и немного помощи из 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);
        }
    }
}
2 голосов
/ 11 марта 2009

См. Выделение слов в 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);
    }
}
...