How do I set different colors for text and underline in JTextPane?

杀马特。学长 韩版系。学妹 提交于 2021-02-07 14:16:58

问题


Just been trying to color the text in JTextPane - but the issue is cannot have different colors for text and the underline. How should I do that or is that even possible? The example below prints all the text and underline in RED.

JTextPane pane = new JTextPane();

StyleContext context = new StyleContext();

Style style = pane.addStyle("Black", null);
StyleConstants.setAlignment(style, StyleConstants.ALIGN_RIGHT);
StyleConstants.setFontSize(style, 14);
StyleConstants.setSpaceAbove(style, 4);
StyleConstants.setSpaceBelow(style, 4);
StyleConstants.setForeground(style, Color.BLACK);

StyledDocument document = pane.getStyledDocument();


style = pane.addStyle("Red Underline", style);
StyleConstants.setForeground(style, Color.RED);
StyleConstants.setUnderline(style, true);

pane.getDocument().insertString(0,  "Test String", style);

回答1:


Here's the solution I found...

Underline StyleConstant in a different colour with AttributeSet

Here's the link to sample code

http://java-sl.com/tip_colored_strikethrough.html

just changing the following line solves it ...

int y = a.getBounds().y + a.getBounds().height + 2 ; 

and it works fine




回答2:


Basically there's 3 classes you need to create:

  • You need to extend javax.swing.text.LabelView to perform modify the view however you wish (whether that's adding an colored underline or not). You will be overriding the paint(Graphics, Shape) method. You can access attributes with this line in the overridden class - the attributes should be the trigger for doing something additional to the text (like adding an underline).

    getElement().getAttributes().getAttribute("attribute name");

  • You need to create a new ViewFactory and overwrite the create method. It's important that when doing this you handle all element types (otherwise things won't quite display right.

  • You need to create an StyledEditorKit to make tell the pane which ViewFactory to use.

Here's a simplified and runnable example of this:

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicTextPaneUI;
import javax.swing.text.*;

public class TempProject extends JPanel{


    public static void main(String args[])    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

                //Adding pane
                JTextPane pane = new JTextPane();
                pane.setEditorKit(new CustomEditorKit());
                pane.setText("Underline With Different Color");

                //Set Style
                StyledDocument doc = (StyledDocument)pane.getDocument();
                MutableAttributeSet attrs = new SimpleAttributeSet();
                attrs.addAttribute("Underline-Color", Color.red);
                doc.setCharacterAttributes(0, doc.getLength()-1, attrs, true);

                JScrollPane sp = new JScrollPane(pane);
                frame.setContentPane(sp);  
                frame.setPreferredSize(new Dimension(400, 300));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);


            }
        });
    }

    public static class CustomEditorKit extends StyledEditorKit{

        public ViewFactory getViewFactory(){
            return new CustomUI();
        }
    }

    public static class CustomUI extends BasicTextPaneUI{
        @Override
        public View create(Element elem){
            View result = null;
            String kind = elem.getName();
            if(kind != null){
                if(kind.equals(AbstractDocument.ContentElementName)){
                    result = new MyLabelView(elem);
                } else if(kind.equals(AbstractDocument.ParagraphElementName)){
                    result = new ParagraphView(elem);
                }else if(kind.equals(AbstractDocument.SectionElementName)){
                    result = new BoxView(elem, View.Y_AXIS);
                }else if(kind.equals(StyleConstants.ComponentElementName)){
                    result = new ComponentView(elem);
                }else if(kind.equals(StyleConstants.IconElementName)){
                    result = new IconView(elem);
                } else{
                    result = new LabelView(elem);
                }
            }else{
                result = super.create(elem);
            }

            return result;
        }
    }

    public static class MyLabelView extends LabelView{

        public MyLabelView(Element arg0) {
            super(arg0);
        }

        public void paint(Graphics g, Shape a){
            super.paint(g, a);
            //Do whatever other painting here;
            Color c = (Color)getElement().getAttributes().getAttribute("Underline-Color");
            if(c != null){
                int y = a.getBounds().y + (int)getGlyphPainter().getAscent(this);
                int x1 = a.getBounds().x;
                int x2 = a.getBounds().width + x1;

                g.setColor(c);
                g.drawLine(x1, y, x2, y);
            }

        }

    }

}

Here's the link to another sample code:

http://java-sl.com/tip_colored_strikethrough.html

This answer is mostly for posterity, I thought adding a simplified version of the linked code and explanation would help make things more understandable.




回答3:


  • for example, and for Html

  • Document returns model to view, there is possible to determine the index where row started / ended



来源:https://stackoverflow.com/questions/12072171/how-do-i-set-different-colors-for-text-and-underline-in-jtextpane

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!