Как установить собственный цвет фона для линии в JTextPane - PullRequest
9 голосов
/ 12 января 2011

Я бы хотел чередовать серый и белый в качестве фона от одной строки моего JTextPane к следующей. Я попытался сделать это, перегрузив метод paintComponent () и нарисовав фон вручную в соответствии с высотой компонента и размером шрифта, но мне это не удалось.

Любые намеки?

Ответы [ 5 ]

2 голосов
/ 12 января 2011

Вы можете использовать подсветку строки ( здесь или здесь ), написанную @VonC в ответ на этот вопрос .

Чтобы выделить альтернативные строки, вы можете использовать его следующим образом:

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

Вот VonC's 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);
                    }
                }
            }
        }
    }
}
1 голос
/ 12 января 2011

Вот пример возможного решения.

Чтобы объяснить это немного, JTextPane - это редактор документов с стилизацией, и поэтому он позволяет изменить StyledDocument , то есть документ, который включает информацию о стиле, например цвет фона для данной линии.

0 голосов
/ 12 января 2011

JTextPane будет принимать HTML-документ как текст. Рассматривали ли вы добавление текста в JTextPane через 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);

Когда вы строите текстовую строку, вы можете установить чередующиеся цвета с помощью css или жестко закодировать ее непосредственно в созданном вами документе. Это поможет вам избежать необходимости переопределять методы перекраски.

Это будет хорошо работать в тех случаях, когда вы не позволите пользователю редактировать поле (т.е. установите false для false). Если вы ожидаете, что это будет перекрашивать строку каждый раз, когда пользователь нажимает клавишу ввода, вам придется адаптировать решение

0 голосов
/ 12 января 2011

Я попытался сделать это, перегрузив метод paintComponent () и нарисовав фон вручную в соответствии с высотой компонента и размером шрифта, но мне это не удалось.

Звучит разумно.Убедитесь, что текстовая панель не является непрозрачной.

Тогда базовый код будет:

  1. нарисуйте свой чередующийся фон на основе области клипа
  2. вызовите super.paintComponent (), чтобы текст был закрашен

Если вам нужна дополнительная помощь, опубликуйте SSCCE , демонстрирующий проблему.

0 голосов
/ 12 января 2011
JTextField someField = new JTextField();
someField.setBackground(Color.GREY );
...