SWTタイマupdate UI


SFTがスレッド内のデータ相互アクセスに関与し、あるスレッドのトリガで別のスレッドのデータにアクセスすると、Invalid thread accessのエラーが報告されます.
SFTで提供されるdisplay.asyncExecメソッドでは、SFTは別のスレッドではなくrunメソッドを1回呼び出しただけなので、Thread.sleepまたはバックグラウンドプログラムの実行時間が長いとプログラムが死んでしまい、応答がありません.
タイマー(スレッド実装)を用いることで,UI updateで死ぬ現象をうまく解決できる.外部から定期的にメッセージを送信してからupdate UIに行く.

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

public class Main {
public static int counter;

public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell();
shell.setLayout(new FillLayout());
shell.setText("Counter");

final Table table = new Main().createTable(shell);

shell.open();
Thread MyThread = new Thread() {
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
return;
}
display.asyncExec(new CMD(table));
}
}
};
MyThread.start();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
MyThread.interrupt();
}

public Table createTable(final Shell shell) {
Table table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setBounds(40, 30, 723, 290);

TableColumn tc1 = new TableColumn(table, SWT.LEFT);
tc1.setText("Column1");
tc1.setWidth(50);

TableColumn tc2 = new TableColumn(table, SWT.LEFT);
tc2.setText("Column2");
tc2.setWidth(200);

TableColumn tc3 = new TableColumn(table, SWT.LEFT);
tc3.setText("Column3");
tc3.setWidth(400);

for(int i=0; i<10; i++) {
TableItem ti = new TableItem(table, SWT.BORDER);
ti.setText(new String[] {(i+1)+"","Column2:value" + (i+1),"Column3:value" + (i+1)});
}
return table;
}
}

class CMD implements Runnable {
private Table table;

public CMD(Table table) {
this.table = table;
}

public void run() {
if(Main.counter TableItem ti = table.getItem(Main.counter++);
ti.setText(new String[] {ti.getText(0), "updated " + ti.getText(1), "updated " + ti.getText(2)});
}
}
}