Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
438 views
in Technique[技术] by (71.8m points)

java - Changing color of selected text in jTextPane

I am creating a text editor using a JTextPane that allows the user to change the color of selected text. But when the user selects the text, then chooses the option to change the color (say, to red) the text does not appear as red until the text is unselected. I tried using setSelectedTextColor to change the color of the selected text, but that doesn't work since that changes the text to red anytime text is selected afterwards. Is there a way to have selected text show up as it's actual color? Or like the way it works in Word where it's not the actual color of the text, but when text of different colors are selected they show up as different colors even when selected.

I use the following code to set up the JTextPane and button that changes the selected text to red:

JButton redButton = new JButton(new StyledEditorKit.ForegroundAction("red", Color.RED));
redButton.setFocusable(false);
buttonPanel.add(redButton);

The JTextPane is set up as with content type HTML and uses the HTMLEditorKit:

p=new JTextPane();
p.setSize(300, 300);
kit = new HTMLEditorKit();
p.setEditorKit(kit);
p.setDocument(kit.createDefaultDocument());

p.setContentType("text/html");
p.setEditable(true);

Let me know if you need more source code to understand the question. Thank You!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Take a look at the DefaultHighlightPainter inner class of DefaultHighlighter.

The method

    public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
        Rectangle alloc = bounds.getBounds();
        try {
            // --- determine locations ---
            TextUI mapper = c.getUI();
            Rectangle p0 = mapper.modelToView(c, offs0);
            Rectangle p1 = mapper.modelToView(c, offs1);

            // --- render ---
            Color color = getColor();

            if (color == null) {
                g.setColor(c.getSelectionColor());
            }
            else {
                g.setColor(color);
            }

As you can see it uses either getColor() or getSelectionColor(). You can extend the class and adapt the highlight painting.

Or use a simpler approach to override your JTextPane's getSelectionColor(). In the method just check whether text is selected and use attributes of selected elements to get desired ccolor. If nothing is selected just return super.getSelectedColor()

UPDATE: Actually applying colors for selection is used on low level GlyphView's public void paint(Graphics g, Shape a) { ... JTextComponent tc = (JTextComponent) c; Color selFG = tc.getSelectedTextColor();

        if (// there's a highlighter (bug 4532590), and
            (tc.getHighlighter() != null) &&
            // selected text color is different from regular foreground
            (selFG != null) && !selFG.equals(fg)) {

            Highlighter.Highlight[] h = tc.getHighlighter().getHighlights();
            if(h.length != 0) {
                boolean initialized = false;
                int viewSelectionCount = 0;
                for (int i = 0; i < h.length; i++) {
                    Highlighter.Highlight highlight = h[i];
                    int hStart = highlight.getStartOffset();
                    int hEnd = highlight.getEndOffset();
                    if (hStart > p1 || hEnd < p0) {
                        // the selection is out of this view
                        continue;
                    }
                    if (!SwingUtilities2.useSelectedTextColor(highlight, tc)) {
                        continue;
                    }

...

As you can see applying selection color vs default color of the view is defined in the SwingUtilities2.useSelectedTextColor(highlight, tc)

In the sources http://kickjava.com/src/com/sun/java/swing/SwingUtilities2.java.htm

 public static boolean useSelectedTextColor(Highlighter.Highlight  JavaDoc h, JTextComponent  JavaDoc c) {
     Highlighter.HighlightPainter  JavaDoc painter = h.getPainter();
     String  JavaDoc painterClass = painter.getClass().getName();
     if (painterClass.indexOf("javax.swing.text.DefaultHighlighter") != 0 &&
             painterClass.indexOf("com.sun.java.swing.plaf.windows.WindowsTextUI") != 0) {
         return false;
     }
     try {
         DefaultHighlighter.DefaultHighlightPainter  JavaDoc defPainter =
                 (DefaultHighlighter.DefaultHighlightPainter  JavaDoc) painter;
         if (defPainter.getColor() != null &&
                 !defPainter.getColor().equals(c.getSelectionColor())) {
             return false;
         }
     } catch (ClassCastException  JavaDoc e) {
         return false;
     }
     return true;
 }

So using the color depends on L&F and painter. If you define your onw painter the color won't be used.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...