0

我有以下课程。

  1. 为什么btnDecorate总是启用?我想在处理循环时禁用该按钮。
  2. 为什么text.redraw()只在循环结束时有效?我想在每个角色上依次看到这个盒子。

 

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

1 回答 1

2

你不能用 SWT 编写这样的循环。

所有 UI 操作都发生在单个 UI 线程上。调用Thread.sleep会使 UI 线程进入睡眠状态,什么都不会发生。

redraw调用仅请求重绘文本,直到下次display.readAndDispatch()运行时才会真正发生,因此在循环中重复执行此操作是行不通的。

您要做的就是运行循环的第一步。然后您必须安排在不阻塞线程的情况下在 500 毫秒后运行下一步。您可以使用以下Display.timerExec方法来请求稍后运行代码:

display.timerExec(500, runnable);

执行下一步runnable的类在哪里。Runnable在此代码结束时,您timerExec再次调用,直到您完成所有步骤。

于 2016-09-01T13:47:55.433 回答