2013-03-11 4 views
1

Я не понимаю, как разделить ядро ​​моей программы с частью GUI моей программы. Действительно, все примеры в Интернете говорят о том, что любое действие GUI должно выполняться с помощью метода SwingUtilities.invokeLater().Ядро Java Swing отдельное ядро ​​с графическим интерфейсом

Проблема в том, что я не понимаю, как я могу использовать этот метод для обработки только моей части GUI и того, как может взаимодействовать ядро ​​и графический интерфейс.

Например, у меня есть класс, которые имеют reponsability графического интерфейса отображения некоторых вычислений:

public class GUI { 
    private JFrame window; 

    public GUI() { 
    window = null; 
    } 

    public void createWindow(int width, int height) { 
    window = new JFrame(); 
    ... 
    window.setVisible(true); 
    } 

    public void displayResults(Calcul results) { 
    /* Some Swing actions. */ 
    } 
} 

и у меня есть ядро ​​моей программы:

public class Core { 
    public static void main(String[] args) { 
    GUI gui = new GUI(); 
    Calcul calculs = new Calcul(); 

    while (true) { 
     /* Make some calculations. */ 
     /* Put results into calcul. */ 
     displayResults(calculs); 
    } 
    } 
} 

Я знаю, что это архитектура не идеальна, но я должен ее использовать. Мой вопрос в том, должен ли я использовать EDT для разделения части GUI и основной части? И, если ответ «да», как я могу это сделать?

Если возможно, мне нужно, чтобы вызовы EDT были прозрачными для пользователя, который использует класс GUI.

EDIT:

ли следующее преобразование класса GUI имеет ожидаемое поведение?

public class GUI { 
    private JFrame window; 

    public GUI() { 
    window = null; 
    } 

    public void createWindowEDT(final int width, final int height) { 
    javax.swing.SwingUtilities.invokeLater(
     new Runnable() { 
     public void run() { 
      createWindow(width, height); 
     } 
     } 
    ); 
    } 

    private void createWindow(final int width, final int height) { 
    window = new JFrame(); 
    ... 
    window.setVisible(true); 
    } 

    public void displayResultsEDT(final Calcul results) { 
    javax.swing.SwingUtilities.invokeLater(
     new Runnable() { 
     public void run() { 
      displayResultsEDT(results); 
     } 
     } 
    ); 
    } 

    private void displayResults(final Calcul results) { 
    /* Some Swing actions. */ 
    } 
} 
+0

10 «но я должен использовать его». Зачем? Почему вы должны использовать эту архитектуру? –

+0

Потому что я должен дать класс людям, которые должны иметь дело с вычислениями и не должны заботиться о своем показе. – benlaug

+1

Положите рабочие потоки в EDT - это способ иметь невосприимчивый графический интерфейс. –

ответ

1

Вы можете скрыть использование Event диспетчерское Thread (EDT) в вашем GUI классе. Его единственное взаимодействие с компонентами Swing, которые должны быть на EDT, учитывая, что это компоненты Swing, которые обычно не являются потокобезопасными.

Нет необходимости в каких-либо синхронизациях в классе GUI, поскольку есть только основной поток приложений, вызывающий GUI.displayResults(Calcul), но если это произойдет, вы можете синхронизировать этот метод или предпринять другие шаги, чтобы избежать ошибок потоковой передачи.

public class GUI 
{ 
    ... 

    public void displayResults(Calcul results) 
    { 
    SwingUtils.invokeLater(
     new Runnable() 
     { 
     public void run() 
     { 
      /* Some Swing actions. */ 
     } 
     } 
    ); 
    } 
} 
+0

Ваш ответ подтверждает мою часть EDIT в исходном сообщении. Большое спасибо ! – benlaug

+0

Да, видел, что после того, как я отправил свой ответ –

+0

Я просто хочу уточнить, что он работает только в том случае, когда Calcul является окончательным. – benlaug

1

Чтобы разместить код GUI в EDT, используйте класс SwingUtilities. Вы должны передать экземпляр Runnable методу invokeLater().

Вы также должны создать свой GUI (call GUI constructor) в EDT.

public static void main(String[] args) { 

    GUI gui = null; 
    Calcul calculs = new Calcul(); 

    SwingUtilities.invokeLater(
     new Runnable() { 
      public void run() { 
       gui = new GUI(); 
      }}); 


    while (true) { 
    /* Make some calculations. */ 
    /* Put results into calcul. */ 
    javax.swing.SwingUtilities.invokeLater(
     new Runnable() { 
      public void run() { 
       gui.displayResults(calculs); 
      }}); 
    } 
    } 
+0

Спасибо. Проблема в том, что такая структура не прозрачна для пользователя класса GUI. Могу ли я узнать ваше мнение о моей части EDIT в оригинальной записи? – benlaug

+1

Все нормально. Я думаю, что есть небольшая проблема с именем метода displayResultsEDT(). Если вы вызовете этот метод, он не будет запускаться в EDT (если вы не вызываете его из EDT). Возможно, в этом методе можно установить SwingUtilities.invokeLater(). Но все в порядке. –

+0

Вы правы. Я сделал «редактирование» с вашим предложением. – benlaug

1

Проблема заключается в том, что вы не можете выполнять вычисления и свой графический интерфейс в той же теме. Если вы это сделаете, ваш графический интерфейс замерзнет, ​​пока ваш код будет делать хруст. Один из подходов - запустить ваши вычисления в отдельном потоке, а затем из этого потока с помощью SwingUtilities.invokeLater() передать ваш графический интерфейс, чтобы он сам обновлялся. Например:

public static void main(String[] args) { 
    final GUI myGUI = new GUI(); 

    Thread workThread = new Thread(new Runnable() { 
     public void run() { 
      // do calculations 

      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        // update GUI 
        myGUI.updateMyResults(); 
       } 
      }); 
     } 
    }); 

    workThread.start(); 
} 
+0

Спасибо. Проблема в том, что такая структура не прозрачна для пользователя класса GUI. Могу ли я узнать ваше мнение о моей части EDIT в оригинальной записи? – benlaug