Java SWT和无效的线程访问

Ang*_*elo 4 java swt multithreading

我已经看过了,但它对我的代码不起作用.这是我独特的课程:

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();
            }
        });
}
Run Code Online (Sandbox Code Playgroud)

该方法doSomething()是另一种方法的调用者,如下所示:

private void doSomething()
{
    Thread th = new Thread() {
        public void run() {
        threadMethod();
        }
    };
    th.start();
}
Run Code Online (Sandbox Code Playgroud)

当我单击我的按钮时,"无效线程访问"从Thread-0引发,并指向threadMethod()(不访问 UI小部件)的第一条指令.我试图用我的按钮监听器包围

Display.getDefault().asyncExec(new Runnable() {
    public void run() {
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

但它也不起作用.我需要该doSomething()方法,因为它在创建线程之前检查一些代码.这是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

        }
    }
Run Code Online (Sandbox Code Playgroud)

为什么我的线程访问无效?谢谢!

Tob*_*lig 6

List是一个SWT小部件,如果你在UI Thread之外调用getItems()方法(在本例中是你的主线程),你会得到一个ERROR_THREAD_INVALID_ACCESS SWTException.这在List API中定义:ERROR_THREAD_INVALID_ACCESS - 如果没有从创建接收器的线程调用

创建接收器的线程是创建显示的线程.如果Display不存在,则第一次调用Display.getDefault()会创建一个.因此,调用open()方法的主线程是UI线程.如果你包装threadMethod()的内容,你的代码将会起作用:

private void threadMethod() {
    Display.getDefault().asyncExec(new Runnable() {
        public void run() {
            // threadMethod contents
        }
    });
} 
Run Code Online (Sandbox Code Playgroud)

然后它将在UI线程中执行.