在swt按钮监听器中刷新gui

时间:2016-09-01 13:35:20

标签: java button swt redraw styledtext

我有下课。

  1. 为什么btnDecorate已全部启用?我想在循环处理时禁用该按钮。
  2. 为什么text.redraw()仅在循环结束时起作用?我希望每个角色都能看到这个盒子。
  3. 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();
    }
    }
    

1 个答案:

答案 0 :(得分:2)

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

所有UI操作都在单个UI线程上进行。调用Thread.sleep会使UI线程进入休眠状态,并且根本不会发生任何事情。

redraw调用仅请求重新绘制文本,直到下次display.readAndDispatch()运行时才会实际发生,因此在循环中重复执行此操作并不起作用。

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

display.timerExec(500, runnable);

其中runnable是实现Runnable的类,用于执行下一步。在此代码的最后,您再次致电timerExec,直到您完成所有步骤。