2012-08-22 31 views
5

Acabo de intentar colorear el texto en JTextPane, pero el problema es que no puede tener diferentes colores para el texto y el subrayado. ¿Cómo debo hacer eso o eso es posible? El siguiente ejemplo imprime todo el texto y el subrayado en ROJO.¿Cómo configuro diferentes colores para texto y subrayado en JTextPane?

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); 
+0

+1 A pesar de que la API de estilo parece ser extensible, no pude encontrar ninguna documentación sobre cómo hacerlo. –

+0

Encontrado respuesta aquí ... http: // stackoverflow.com/questions/9502654/underline-styleconstant-in-a-different-color-with-attributeset –

+0

Publique eso como respuesta –

Respuesta

4

Básicamente hay 3 clases que necesita crear:

  • Necesita extender javax.swing.text.LabelView para realizar modificar la vista como lo desee (ya sea que se esté agregando un subrayado de color o no). Va a anular el método paint(Graphics, Shape). Puede acceder a los atributos con esta línea en la clase anulada: los atributos deben ser el activador para hacer algo adicional al texto (como agregar un subrayado).

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

  • Es necesario crear un nuevo ViewFactory y sobrescribir el método create. Es importante que cuando se hace esto puede manejar todos los tipos de elementos (de lo contrario las cosas no del todo mostrar derecha.

  • Es necesario crear un StyledEditorKit para que diga el panel, que ViewFactory de usar.

está aquí un ejemplo simplificado y ejecutable de esta:

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); 
      } 

     } 

    } 

} 

Aquí está el enlace a otro código de ejemplo:

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

Esta respuesta es principalmente para la posteridad, pensé que agregar una versión simplificada del código vinculado y la explicación ayudaría a hacer las cosas más comprensibles.

+0

bien descrito +1 – mKorbel

Cuestiones relacionadas