2011-01-12 14 views
9

Chciałbym przełączać się między szarym i białym jako tło z jednej linii mojego JTextPane do następnego. Próbowałem to zrobić przez przeciążenie metody paintComponent() i ręczne rysowanie tła zgodnie z wysokością komponentu i wielkości czcionki, ale mi się nie udało.Jak ustawić niestandardowy kolor tła na linii w JTextPane

Jakieś wskazówki?

+0

Co masz na myśli przez "jedną linię"? Czy funkcja setBackground() nie będzie działać, jeśli zmienisz kolor, którego używasz? – jzd

+0

Czy edytujesz swój tekst? np. czy chcesz zmienić tło, jeśli linie są dodawane/usuwane? – dogbane

Odpowiedz

2

Możesz użyć zakreślacza linii (here lub here) napisanego przez @VonC, w odpowiedzi na this question.

W celu podkreślenia alternatywne linie można go używać w następujący sposób:

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

Oto VonC na MyHighlighter:

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 Miałem na myśli JTextPane, a nie JTextField ... Poprawiłem to pytanie. – jumar

+0

Niestety, ten zmieni ** cały ** kolor JTextPane, a nie tylko jeden z jego linii. – Riduidel

+0

@Riduidel, tak, ale sposób, w jaki pierwotnie sformułowano to pytanie, miał sens. – jzd

1

Oto an example z możliwego rozwiązania.

Aby to wyjaśnić, JTextPane jest edytorem dokumentów w stylu i jako taki umożliwia zmianę StyledDocument, czyli dokumentu, który zawiera informacje o stylu, takie jak kolor tła dla danej linii.

0

Próbowałem to zrobić przez przeciążenie metody paintComponent() i ręczne rysowanie tła zgodnie z wysokością komponentu i wielkości czcionki, ale mi się nie udało.

Brzmi rozsądnie. Upewnij się, że panel tekstowy nie jest nieprzezroczysty.

Następnie kod podstawowy byłoby:

  1. pomalować swoją tło zmienny w zależności od regionu klipu
  2. invoke super.paintComponent(), więc tekst jest zamalowane górze tle.

Jeśli potrzebujesz więcej pomocy, opublikuj SSCCE, demonstrując problem.

-1

JTextPane odbędzie dokument HTML jako tekst. Czy rozważałeś dodanie swojego tekstu do JTextPane poprzez dokument 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); 

Kiedy budować łańcuch tekstowy, można ustawić kolory na przemian z CSS, lub ciężko kodem go bezpośrednio do utworzony dokument. Pomoże Ci to uniknąć konieczności nadpisywania metod odświeżania.

To zadziała dobrze w sytuacjach, gdy nie zezwolisz użytkownikowi na edycję ramki (np. SetEditable na false) Jeśli spodziewasz się, że odświeży linię za każdym razem, gdy użytkownik uderzy klawisz Enter, będziesz musiał dostosować rozwiązanie

Powiązane problemy