SWTException: недопустимый доступ к потоку возникает при попытке вызвать updateButtons() из панели на странице мастера

#java #multithreading

#java #многопоточность

Вопрос:

Мне нужно включить / отключить Finish кнопку на WizardDialog в зависимости от некоторого поля, которое присутствует на панели, расположенной внутри WizardPage .

Ниже приведен код для открытия диалогового окна мастера:

 UserWizardDialog dialog = new UserWizardDialog(window.getShell(), new UserWizard(window.getShell()));
dialog.open();
  

Внутри этого UserWizard есть WizardPage вызываемый CustomerWizardPage , который имеет CustomerPanel . На этой панели у меня есть поле Customer PIN , в зависимости от значения которого я должен включить / отключить Finish кнопку на UserWizardDialog .

В ItemListener случае появления этого поля на панели я добавляю приведенный ниже код:

 parent.getWizard().getContainer().updateButtons();
  

Но это приводит к исключению:

 org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:3884)
at org.eclipse.swt.SWT.error(SWT.java:3799)
at org.eclipse.swt.SWT.error(SWT.java:3770)
at org.eclipse.swt.widgets.Widget.error(Widget.java:463)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:355)
at org.eclipse.swt.widgets.Control.setEnabled(Control.java:2923)
at org.eclipse.jface.wizard.WizardDialog.updateButtons(WizardDialog.java:1257)
at com.noi.rac.dhl.eco.util.components.CustomerPanel$4.itemStateChanged(CustomerPanel.java:304)
  

Ответ №1:

«Недопустимый доступ к потоку» возникает при изменении компонентов пользовательского интерфейса в потоке, отличном от пользовательского интерфейса.

Чтобы избежать этого исключения, вам следует изменить компоненты пользовательского интерфейса в потоке пользовательского интерфейса. Я думаю, что в вашем исходном коде вам следует обновить свои кнопки в потоке пользовательского интерфейса.

Например:

 Display.getDefault().asyncExec(new Runnable() {
    @Override
    public void run() {
        parent.getWizard().getContainer().updateButtons();
    }
});
  

Вы можете использовать syncExec() или asyncExec() в зависимости от ваших потребностей.

Надеюсь, это вам поможет.