2016-08-05 4 views
0

Я использую SWT в основной графической программе. Внутри я создаю другой поток для запуска некоторых программ. Однако, если некоторые ошибки встречаются в этих процессах, я хочу сообщить об этом пользователю, создав окно сообщения. Поскольку в SWT только один поток может выполнять операции с графическим интерфейсом, у меня были исключения для исключения run-run, поэтому поток GUI мог бы справиться с ними. Однако у меня возникают проблемы, потому что я создаю новый поток для бегуна программы (чтобы не задерживать поток GUI, который будет постоянно обновлять и обновлять некоторые графики), но в результате исключения, которые имеют место, застревают как часть этого потока, который не может создать окно сообщения об ошибке. Любые предложения о том, как с этим бороться? .SWT, несколько потоков и исключений

private void goButtonActionPerformed() 
{ 
    // create the program runner object 
    ProgramRunner PR = new ProgramRunner(); // real code passes in data to be used 

    try{ 
     // check all necessary parameters are entered 
     boolean paramsOK = PR.checkParams(); 
     if (paramsOK) 
     { 
      // all necessary information is available. Start Processing. 
      Thread t = new Thread() { 
       public void run() 
       { 
        try{ 
         PR.runPrograms(); 
        } 
        catch (IOException iox) 
        { 
         // This does not work to catch & display the exceptions 
         // which took place in PR.runPrograms(), because this 
         // thread is not allowed to perform GUI operations. 
         // However, I don't know how to pass this 
         // exception/error notification out of this thread. 
         MessageBox mb = new MessageBox(m_Shell, SWT.ICON_ERROR); 
         mb.setMessage(iox.getMessage()); 
         mb.open(); 
        } 
       } 
      }; 
      t.start(); 
     } 
    } 
    catch (IOException iox) 
    { 
     // this works to catch & display the exceptions which took place 
     // in PR.checkParams() because that is not a separate thread 
     MessageBox mb = new MessageBox(m_Shell, SWT.ICON_ERROR); 
     mb.setMessage(iox.getMessage()); 
     mb.open(); 
    } 
+0

О, и я понимаю, что PR.checkParams() не нужно возвращать логическое значение, которое нужно проверить, потому что вместо того, чтобы возвращать false, оно просто забросило бы исключение, которое будет обрабатываться здесь. – sacrawford

ответ

1

обруча улова логика внутри Display.getDefault() asyncExec для отображения сообщений об ошибках на UI потоке:

Thread t = new Thread() 
{ 
    public void run() 
    { 
     try 
     { 
      PR.runProgram(); 
     } 
     catch (final IOException iox) 
     { 
      Display.getDefault().asyncExec(new Runnable() 
      { 
       public void run() 
       { 
        MessageBox mb = new MessageBox(m_Shell, SWT.ICON_ERROR); 
        mb.setMessage(iox.getMessage()); 
        mb.open(); 

       } 
      }); 

     } 
    } 
}); 

t.start(); 

исключения могут отображаться в UI потоке тогда.

0

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

syncExec приостанавливает текущий поток до тех пор, пока код UI не будет запущен. asyncExec не приостанавливает поток и запускает код пользовательского интерфейса как можно скорее.

Вы можете получить текущее изображение в любом потоке используя Display.getDefault() так что вы могли бы сделать что-то вроде:

Display.getDefault().asyncExec(() -> 
{ 
    if (m_Shell != null && !m_Shell.isDisposed()) { 
    MessageBox mb = new MessageBox(m_Shell, SWT.ICON_ERROR); 
    mb.setMessage(iox.getMessage()); 
    mb.open(); 
    } 
}); 

Я использовал лямбда-выражения Java 8 для Runnable здесь, как это короче, чем традиционный метод.

Поскольку этот код выполняется асинхронно, рекомендуется проверить, что оболочка не является нулевой и не была удалена.

Смежные вопросы