I have following class.
btnDecorate
is allways enabled? I wanted to disable the button when the loop is under processing.text.redraw()
works only in the end of loop? I wanted to see the box sequently on every character.
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class SampleRefreshStyledText {
public static void main(String[] args) {
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout(SWT.VERTICAL));
final Button btnDecorate = new Button(shell, SWT.NONE);
btnDecorate.setText("Decorate");
final StyledText text = new StyledText(shell, SWT.NONE);
text.setText("ABCDEFGHIJKLMNOPRQ\n1234567890");
btnDecorate.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent event) {
btnDecorate.setEnabled(false);
for (int i = 0; i < text.getText().length(); i++) {
StyleRange styleRange = new StyleRange();
styleRange.start = i;
styleRange.length = 1;
styleRange.borderColor = display.getSystemColor(SWT.COLOR_RED);
styleRange.borderStyle = SWT.BORDER_SOLID;
styleRange.background = display.getSystemColor(SWT.COLOR_GRAY);
text.setStyleRange(null);
text.setStyleRange(styleRange);
text.redraw();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
btnDecorate.setEnabled(true);
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
You can't write loops like this with SWT.
All UI operations occur on the single UI thread. Calling Thread.sleep
puts the UI thread to sleep and nothing at all will happen.
The redraw
call only requests that the text is redrawn, it will not actually happen until the next time the display.readAndDispatch()
is run, so doing this repeatedly in a loop doesn't work.
What you have to do is run the first step of your loop once. You must then arrange to run the next step 500ms later without blocking the thread. You can do this using the Display.timerExec
method to request that code is run at a later time:
display.timerExec(500, runnable);
where runnable
is a class implementing Runnable
that does the next step. At the end of this code you call timerExec
again until you have worked your way through all the steps.