Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java SWT show Line numbers for StyledText

I was wondering if there is a straightforward way to display line numbers with StyledText text field - even if lines are wrapped. I'm using it in my application and if content gets to big, some line numbers would be nice.

Thank you.

like image 835
kon Avatar asked Jun 15 '12 20:06

kon


2 Answers

The key is org.eclipse.swt.custom.Bullet. It's basically a symbol (or in our case a number) you can add to the beginning of a line.

//text is your StyledText
text.addLineStyleListener(new LineStyleListener()
{
    public void lineGetStyle(LineStyleEvent e)
    {
        //Set the line number
        e.bulletIndex = text.getLineAtOffset(e.lineOffset);

        //Set the style, 12 pixles wide for each digit
        StyleRange style = new StyleRange();
        style.metrics = new GlyphMetrics(0, 0, Integer.toString(text.getLineCount()+1).length()*12);

        //Create and set the bullet
        e.bullet = new Bullet(ST.BULLET_NUMBER,style);
    }
});
like image 124
RedHatter Avatar answered Oct 10 '22 00:10

RedHatter


This is my working implementation.

styledText.addLineStyleListener(new LineStyleListener() {
    @Override
    public void lineGetStyle(LineStyleEvent event) {
        // Using ST.BULLET_NUMBER sometimes results in weird alignment.
        //event.bulletIndex = styledText.getLineAtOffset(event.lineOffset);
        StyleRange styleRange = new StyleRange();
        styleRange.foreground = Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
        int maxLine = styledText.getLineCount();
        int bulletLength = Integer.toString(maxLine).length();
        // Width of number character is half the height in monospaced font, add 1 character width for right padding.
        int bulletWidth = (bulletLength + 1) * styledText.getLineHeight() / 2;
        styleRange.metrics = new GlyphMetrics(0, 0, bulletWidth);
        event.bullet = new Bullet(ST.BULLET_TEXT, styleRange);
        // getLineAtOffset() returns a zero-based line index.
        int bulletLine = styledText.getLineAtOffset(event.lineOffset) + 1;
        event.bullet.text = String.format("%" + bulletLength + "s", bulletLine);
    }
});
styledText.addModifyListener(new ModifyListener() {
    @Override
    public void modifyText(ModifyEvent e) {
        // For line number redrawing.
        styledText.redraw();
    }
});

Note that the possible overhead of syntax highlighting recalculation when calling redraw() is likely to be acceptable, because lineGetStyle() are only called with lines currently on screen.

like image 24
Hai Zhang Avatar answered Oct 09 '22 23:10

Hai Zhang