2011-01-12 13 views
9

Me gustaría alternar entre gris y blanco como fondo de una línea de mi JTextPane a la siguiente. Intenté hacer esto sobrecargando el método paintComponent() y dibujando el fondo de forma manual de acuerdo con la altura del componente en un Tamaño de fuente pero no tuve éxito.Cómo establecer un color de fondo personalizado en una línea en un JTextPane

¿Alguna pista?

+0

¿Qué quiere decir con "una línea"? ¿No funcionará setBackground() si alterna el color que usa? – jzd

+0

¿es editable su cuadro de texto? es decir, ¿desea que los fondos cambien si se agregan/eliminan líneas? – dogbane

Respuesta

2

Puede usar el resaltador de línea (here o here), escrito por @VonC, en respuesta al this question.

Con el fin de poner de relieve las líneas alternas que se pueden utilizar de la siguiente manera:

public static void main(String[] args) { 

    JTextPane t = new JTextPane(); 
    t.setSelectionColor(new Color(1.0f, 1.0f, 1.0f, 0.0f)); 
    Highlighter hilite = new MyHighlighter(); 
    t.setHighlighter(hilite); 
    t.setText("Line1\nLine2\nLine3\nLine4\nLine5\n"); 


    DefaultHighlightPainter whitePainter = new DefaultHighlighter.DefaultHighlightPainter(Color.WHITE); 
    DefaultHighlightPainter grayPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.GRAY); 

    try { 
     Document doc = t.getDocument(); 
     String text = doc.getText(0, doc.getLength()); 
     int start = 0; 
     int end = 0 ; 

     boolean even = true; 

     //look for newline char, and then toggle between white and gray painters. 
     while ((end = text.indexOf('\n', start)) >= 0) { 
      even = !even; 
      DefaultHighlightPainter painter = even ? grayPainter : whitePainter; 
      hilite.addHighlight(start, end+1, painter); 
      start = end+1; 
     } 
    } catch (BadLocationException e) { 
     e.printStackTrace(); 
    } 

    JPanel p = new JPanel(new BorderLayout());  
    p.add(t, BorderLayout.CENTER); 
    JFrame f = new JFrame(); 
    f.add(p); 
    f.setSize(100, 100); 
    f.setVisible(true); 
} 

Aquí es de MyHighlighter VonC:

class MyHighlighter extends DefaultHighlighter 
{ 

    private JTextComponent component; 

    /** 
    * @see javax.swing.text.DefaultHighlighter#install(javax.swing.text.JTextComponent) 
    */ 
    @Override 
    public final void install(final JTextComponent c) 
    { 
     super.install(c); 
     this.component = c; 
    } 

    /** 
    * @see javax.swing.text.DefaultHighlighter#deinstall(javax.swing.text.JTextComponent) 
    */ 
    @Override 
    public final void deinstall(final JTextComponent c) 
    { 
     super.deinstall(c); 
     this.component = null; 
    } 

    /** 
    * Same algo, except width is not modified with the insets. 
    * 
    * @see javax.swing.text.DefaultHighlighter#paint(java.awt.Graphics) 
    */ 
    @Override 
    public final void paint(final Graphics g) 
    { 
     final Highlighter.Highlight[] highlights = getHighlights(); 
     final int len = highlights.length; 
     for (int i = 0; i < len; i++) 
     { 
      Highlighter.Highlight info = highlights[i]; 
      if (info.getClass().getName().indexOf("LayeredHighlightInfo") > -1) 
      { 
       // Avoid allocing unless we need it. 
       final Rectangle a = this.component.getBounds(); 
       final Insets insets = this.component.getInsets(); 
       a.x = insets.left; 
       a.y = insets.top; 
       // a.width -= insets.left + insets.right + 100; 
       a.height -= insets.top + insets.bottom; 
       for (; i < len; i++) 
       { 
        info = highlights[i]; 
        if (info.getClass().getName().indexOf(
          "LayeredHighlightInfo") > -1) 
        { 
         final Highlighter.HighlightPainter p = info 
           .getPainter(); 
         p.paint(g, info.getStartOffset(), info 
           .getEndOffset(), a, this.component); 
        } 
       } 
      } 
     } 
    } 
} 
0
JTextField someField = new JTextField(); 
someField.setBackground(Color.GREY); 
+0

Sory quise decir JTextPane, no JTextField ... He corregido la pregunta. – jumar

+0

Desafortunadamente, este cambiará el ** color ** JTextPane, y no solo una de sus líneas. – Riduidel

+0

@Riduidel, sí, pero la forma en que la pregunta fue redactada originalmente tenía sentido. – jzd

1

Aquí está an example de una posible solución.

Para explicarlo un poco, JTextPane es un editor de documentos con estilo, y como tal, permite cambiar StyledDocument, es decir, un documento que incluye información de estilo, como el color de fondo para una línea determinada.

0

Intenté hacer esto sobrecargando el método paintComponent() y dibujando el fondo manualmente de acuerdo con la altura del componente un tamaño de fuente pero no tuve éxito.

Suena razonable. Asegúrese de que el panel de texto no sea opaco.

A continuación, el código básico sería:

  1. pintar su fondo alterna basada en la región de recorte
  2. super.paintComponent invoke() para que el texto se pinta sobre la parte superior del fondo.

Si necesita más ayuda, publique el SSCCE para demostrar el problema.

-1

JTextPane tomará un documento HTML como texto. ¿Ha considerado agregar su texto al JTextPane a través de un documento HTML?

JTextPane pane = new JTextPane(); 
pane.setContentType("text/html"); 

String text = /*some html table or set of divs for formatting */ 

pane.setText(text); 

myJFrame.add(pane); 

Cuando se construye la cadena de texto, puede configurar los colores alternando con css, o codificar directamente en el documento que ha creado. Esto lo ayudará a evitar tener que anular los métodos de repintado.

Esto funcionará bien en los casos en que no permita que el usuario edite el cuadro (es decir, setEditable en falso) Si espera que vuelva a pintar la línea cada vez que el usuario presione la tecla Intro, tendrá que adaptar el solución

Cuestiones relacionadas