Reputation: 937
I've seen this but it doesn't work for my code. This is my unique class:
public static void main(String[] args) {
try {
Main window = new Main();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
protected void createContents() {
shell = new Shell(SWT.CLOSE | SWT.MIN | SWT.TITLE | SWT.ON_TOP);
shell.setSize(301, 212);
shell.setText("MyShell");
// ...Other contents...
btn = new Button(shell, SWT.NONE);
btn.setBounds(114, 151, 76, 25);
btn.setText("BUTTON!");
btn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
doSomething();
}
});
}
The method doSomething()
is a caller for another method, like this:
private void doSomething()
{
Thread th = new Thread() {
public void run() {
threadMethod();
}
};
th.start();
}
When I click my button, an "Invalid Thread Access" raises from Thread-0, and it points to the first instruction of threadMethod()
(wich doesn't access to UI widgets). I've tried to surround my button listener with
Display.getDefault().asyncExec(new Runnable() {
public void run() {
// ...
}
});
but it doesn't work either. I need the doSomething()
method because it checks some code before creating the thread.
This is threadMethod()
private void threadMethod()
{
String[] listItems = list.getItems();
String fileName;
Path source, target;
File folder = new File(dir + File.separator);
if (!folder.exists()) {
folder.mkdir();
}
try
{
for(int i = 0; i < list.getItemCount(); i++)
{
// do something with non UI widgets
}
list.removeAll();
}
catch(IOException | InterruptedException e)
{
//print error
}
}
Why I've got Invalid thread access? Thank you!
Upvotes: 6
Views: 6441
Reputation: 1144
List is an SWT widget and if you call the getItems() method on it outside of the UI Thread (in this case your main thread), you get an ERROR_THREAD_INVALID_ACCESS SWTException. This is defined in the List API: ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
The Thread that created the receiver, is the the thread that created the Display. If a Display does not exist, the first call to Display.getDefault() creates one. Therefore your main thread, which calls the open() method, is the UI thread. Your code will work if you wrap the contents of the threadMethod():
private void threadMethod() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
// threadMethod contents
}
});
}
It will then be executed in the UI thread.
Upvotes: 8