9

JTextPane のある行から次の行への背景として灰色と白を交互に使用したいと考えています。paintComponent() メソッドをオーバーロードし、コンポーネントの高さとフォント サイズに従って手動で背景を描画することでこれを実行しようとしましたが、成功しませんでした。

ヒントはありますか?

4

5 に答える 5

2

この質問への回答として、@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があり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);
                    }
                }
            }
        }
    }
}
于 2011-01-12T17:35:59.017 に答える
1

考えられる解決策の例を次に示します。

少し説明すると、JTextPaneはスタイル付きドキュメント エディタであり、StyledDocumentを変更できます。つまり、特定の行の背景色などのスタイル情報を含むドキュメントを変更できます。

于 2011-01-12T16:05:06.270 に答える
0
JTextField someField = new JTextField();
someField.setBackground(Color.GREY );
于 2011-01-12T15:48:49.983 に答える
0

paintComponent() メソッドをオーバーロードし、コンポーネントの高さとフォント サイズに従って手動で背景を描画することでこれを実行しようとしましたが、成功しませんでした。

合理的に聞こえます。テキスト ペインが不透明でないことを確認します。

次に、基本的なコードは次のようになります。

  1. クリップ領域に基づいて交互の背景をペイントします
  2. super.paintComponent() を呼び出して、テキストが背景の上にペイントされるようにします。

さらに支援が必要な場合は、問題を示すSSCCEを投稿してください。

于 2011-01-12T16:05:25.217 に答える
-1

JTextPaneは、HTMLドキュメントをテキストとして受け取ります。HTMLドキュメントを介してテキストをJTextPaneに追加することを検討しましたか?

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を使用して交互の色を設定するか、作成したドキュメントに直接ハードコーディングすることができます。これにより、repaintメソッドをオーバーライドする必要がなくなります。

これは、ユーザーがボックスを編集できない場合(つまり、setEditableをfalseに設定する場合)にうまく機能します。ユーザーがEnterキーを押すたびに行が再描画されると予想される場合は、ソリューションを調整する必要があります。

于 2011-01-12T17:43:37.347 に答える