Lately, I have been writing a SWT GUI application that parses a (relatively large in size) log file and displays the data in a UI Tree.
Since parsing the log file could take up to ten or more seconds, I wanted to add a ProgressBar element to my UI.
I also had to make my long running operation run in its own thread so as to not block the UI. After a few trial and error attempts
and some googling, I figured how things should happen (see below code - with comments).
Basically, what needs to be kept in mind:
✓ the long running operation should run in its own thread concurrently to the UI thread.
✓ when the non UI thread needs to access UI elements in needs to do so by invoking the asyncExec method of the shell.
Otherwise, SWT illegal thread access exceptions will be thrown.
public void widgetSelected(SelectionEvent event) {
FileDialog fd = new FileDialog(gui.getShell(), SWT.OPEN);
...
final String filename = fd.open();
//My long running operation (parsing a log file in this case) should execute in its own thread.
Thread th = new Thread("log file parser") {
public void run() {
//Before parsing the log file we want to enable a visual indicator in the GUI
//for instance in our case a (indeterminate) progress bar.
//since SWT won't let us access UI elements from a non-UI thread we have to
//use asyncExec.
gui.getDisplay().asyncExec(new Runnable() {
public void run() {
gui.enableProgressBar(true);
}
});
//we parse the log file. Remember we are still in our new non-UI thread.
parser.parseFile(filename);
//After parsing the log file, we want to disable the visual indicator (i.e.
//the progress bar and update other UI elements.
gui.getDisplay().asyncExec(new Runnable() {
public void run() {
gui.enableProgressBar(false);
//post-parsing work like populating a Tree or a Table.
tree.removeAll();
TreeItem rootTreeItem = new TreeItem(tree, 0);
rootTreeItem.setText(parser.getRootNode().getName());
rootTreeItem.setData(parser.getRootNode());
new TreeItem(rootTreeItem, 0);
}
});
}
};
//we kickoff our thread. Remember that the current thread (the one
//in which our widgetSelected method is executing) is the main UI thread.
th.start();
} //end widgetSelected
I hope this proves helpful to you when coding SWT apps.