Java SWT and Invalid Thread Access

女生的网名这么多〃 提交于 2019-11-28 08:52:51

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/15851562/java-swt-and-invalid-thread-access

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!