2016-09-01 16 views
0

다음 클래스가 있습니다.swt 버튼 리스너에서 gui 새로 고침

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

답변

2

당신은 SWT와 같은 루프를 쓸 수 없습니다.

모든 UI 작업은 단일 UI 스레드에서 발생합니다. Thread.sleep을 호출하면 UI 스레드가 잠자기 상태가되고 아무 것도 일어나지 않습니다.

호출은 텍스트가 다시 그려지기를 요청하며 다음 번에 display.readAndDispatch()이 실행될 때까지 실제로 수행되지 않으므로 루프에서이 작업을 반복적으로 수행하면 작동하지 않습니다.

루프의 첫 단계를 한 번 실행하면됩니다. 그런 다음 스레드을 차단하지 않고 다음 단계 500ms 후에 을 실행해야합니다. 당신은 그 코드는 나중에 실행 요청하기 위해 Display.timerExec 방법을 사용하여이 작업을 수행 할 수 있습니다 runnable 다음 단계를 수행 Runnable를 구현하는 클래스가

display.timerExec(500, runnable); 

. 이 코드가 끝나면 모든 단계를 진행할 때까지 timerExec으로 다시 전화하십시오.