在 swt 按钮侦听器中刷新 gui
refresh gui in swt button listener
我关注class。
- 为什么
btnDecorate
总是启用?我想在处理循环时禁用按钮。
- 为什么
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();
}
}
您不能使用 SWT 编写这样的循环。
所有 UI 操作都发生在单个 UI 线程上。调用 Thread.sleep
会使 UI 线程进入休眠状态,什么都不会发生。
redraw
调用只请求重绘文本,直到下一次 display.readAndDispatch()
是 运行 才会真正发生,所以在循环中重复这样做不会没用。
你要做的是运行循环的第一步。然后,您必须安排 运行 500 毫秒后 下一步而不阻塞线程 。您可以稍后使用 Display.timerExec
方法请求代码为 运行 来执行此操作:
display.timerExec(500, runnable);
其中 runnable
是执行下一步的 class 实现 Runnable
。在此代码的末尾,您再次调用 timerExec
,直到完成所有步骤。
我关注class。
- 为什么
btnDecorate
总是启用?我想在处理循环时禁用按钮。 - 为什么
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();
}
}
您不能使用 SWT 编写这样的循环。
所有 UI 操作都发生在单个 UI 线程上。调用 Thread.sleep
会使 UI 线程进入休眠状态,什么都不会发生。
redraw
调用只请求重绘文本,直到下一次 display.readAndDispatch()
是 运行 才会真正发生,所以在循环中重复这样做不会没用。
你要做的是运行循环的第一步。然后,您必须安排 运行 500 毫秒后 下一步而不阻塞线程 。您可以稍后使用 Display.timerExec
方法请求代码为 运行 来执行此操作:
display.timerExec(500, runnable);
其中 runnable
是执行下一步的 class 实现 Runnable
。在此代码的末尾,您再次调用 timerExec
,直到完成所有步骤。