SWT StyledText: Position caret of the next line to tab width of the previous line

689 Views Asked by At

I am developing an (rich) editor based on SWT StyledText. There is one feature that I until now cannot solve it. I want my editor to place the cursor at the tab width as the beginning of the previous line when the user presses Ctrl+u (similar to Eclipse or Notepad++ when users press Enter key). I've tried several methods but nothing works for me. Please take a look at my example. Every suggestion is welcome. Thanks in advance.

StyledText text = new StyledText(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
    text.setTabs(5);
    text.setText("");
    text.setLeftMargin(5);
    text.setBounds(0, 0, 512, 391);
    text.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            int currentLine = text.getLineAtOffset(text.getCaretOffset());
            int currCaretOffset = text.getCaretOffset();
            if(e.stateMask == SWT.CTRL && e.keyCode == 'u'){
                //text.setIndent(text.getOffsetAtLine(currentLine));//doesn't work
                text.append("\n");
                //text.append("\t");//doesn't work
                text.setCaretOffset(text.getCharCount()+text.getTabs());//doesn't work
                System.out.println("caret offset "+text.getCaretOffset());
            }               
        }
    });
1

There are 1 best solutions below

3
Baz On BEST ANSWER

If I understand you correctly, you'd like to move the cursor to the next line and indent it by as many "white spaces" as there are leading spaces in the previous line.

I'm surprised there isn't a better way to do this (or maybe I just haven't found one), but this will do the job:

private static final int TAB_WIDTH = 5;

public static void main(String[] args)
{
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("Stackoverflow");
    shell.setLayout(new FillLayout());

    StyledText text = new StyledText(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
    text.setTabs(TAB_WIDTH);
    text.setText("");
    text.setLeftMargin(5);
    text.setBounds(0, 0, 512, 391);
    text.addListener(SWT.KeyUp, (e) -> {
        if (e.stateMask == SWT.CTRL && e.keyCode == 'u')
        {
            int currentLine = text.getLineAtOffset(text.getCaretOffset());
            String textAtLine = text.getLine(currentLine);
            int spaces = getLeadingSpaces(textAtLine);
            text.insert("\n");
            text.setCaretOffset(text.getCaretOffset() + 1);
            for (int i = 0; i < spaces; i++)
                text.append(" ");

            text.setCaretOffset(text.getCaretOffset() + spaces);
        }
    });

    shell.pack();
    shell.open();
    shell.setSize(400, 300);

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

private static int getLeadingSpaces(String line)
{
    int counter = 0;

    char[] chars = line.toCharArray();
    for (char c : chars)
    {
        if (c == '\t')
            counter += TAB_WIDTH;
        else if (c == ' ')
            counter++;
        else
            break;
    }

    return counter;
}