Кто-нибудь может объяснить мне этот метод свинга javax? - PullRequest
7 голосов
/ 30 января 2010

У меня проблемы с пониманием этого простого кода:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
      createAndShowGUI();
   }
});

Кто-нибудь может объяснить мне, как это работает (простыми словами, потому что я новичок)? Этот короткий код является частью этого большего кода .

Если говорить более конкретно, у меня есть следующие вопросы:

  1. Определяет ли "public void run" новый метод? Если это так, почему он определен в другом методе (см. «Код большего размера» для справки)?
  2. Если «public void run» определяет новые методы, то для чего нужно определять метод, содержащий только одну строку кода (createAndShowGUI)?
  3. Что делает "invokeLater"? На самом деле это самый сложный вопрос для меня.

Я хотел бы еще раз подчеркнуть, что я новичок, и использование «специальных» и «технических» слов вызовет еще больше вопросов.

Заранее спасибо, если решите мне помочь!

Ответы [ 5 ]

11 голосов
/ 30 января 2010

Самый короткий ответ, который я могу дать:

Runnable - это интерфейс в Java, представляющий тип, который определяет метод run. Любой класс, который реализует этот интерфейс, должен обеспечить реализацию для run. Runnable s представляют задачи, которые должны выполняться другими частями вашей системы. Thread является известным Runnable.

Если у вас есть код, похожий на new InterfaceName() { //implementation }, он называется анонимным классом. Задача анонимного класса - создать одноразовый класс, реализующий тип интерфейса. У этого класса нет имени, и поэтому мы никогда не сможем обратиться к нему снова. Он используется только здесь.

Не зная ничего о Swing, похоже, что SwingUtilities.invokeLater() принимает Runnable и ... что ж, я думаю, он вызывает его позже (насколько позже, вероятно, описано в JavaDocs) Но причина, по которой вы определяете run здесь как просто другой вызов метода, заключается в том, что некоторый код внутри SwingUtilities будет вызывать метод run для этого Runnable; действительно, все, что он может знать о любом Runnable, - это то, что он определяет метод с сигнатурой public void run(), потому что это единственный метод, определенный в интерфейсе Runnable.

Ну, я думаю, это было не так уж и мало.

6 голосов
/ 30 января 2010

Это анонимный внутренний класс .

Вы определяете три вещи:

  • Новый класс
  • Метод с именем run в этом классе
  • Новый экземпляр этого класса

В этом примере некоторые операции (createAndShowGUI()) должны выполняться в потоке Swing. Вы не можете «перейти» в другой поток в середине вызова метода, поэтому вместо этого вы помещаете объект (новый созданный вами экземпляр) в очередь. Когда поток Swing будет готов, он удалит этот объект из очереди и вызовет ваш метод run, который, в свою очередь, вызовет createAndShowGUI. Теперь все происходит в правильной ветке.

2 голосов
/ 30 января 2010

Хотя именно так Swing обычно создает графический интерфейс, все, что они делают, это говорят вам «просто сделайте это так, мы объясним почему позже». И я думаю, что они правы, потому что детали несколько сложны и бесполезны для новичка. Но все равно:

invokeLater запускает поток, который будет запускать класс Runnable позже. Класс runnable создается ad hoc, как упомянуто finnw через new Runnable { [..] }, и должен указывать метод public void run() в соответствии с интерфейсом Runnable. В этом случае все, что он делает, это выполняет метод createAndShowGUI.

1 голос
/ 30 января 2010

Этот код заставляет функцию (createAndShowGUI ()) вызываться в другом потоке. Если вы не знаете, что такое поток, лучше прочитайте об этом, но в любом случае, думайте о нем как о коде, который выполняется одновременно с другим кодом. Другим кодом будут строки, следующие за этим вызовом Invoke (). Это очень распространено в графических приложениях, код запускается для обновления графики, в то время как другой код реагирует на действия пользователя. Тем не менее, я не удосужился прочитать документацию по InvokeLater (), и не написал слишком много Java в моей жизни. Как сказал «LumpN», «именно так Swing обычно создает графический интерфейс».

Более странно (для новичка) то, что параметр invokeLater () определяется анонимным способом - «внутри кода». Это на самом деле хорошая вещь, так как этот класс не так прост, как новый. Все остальные ответы объяснили анонимную вещь.

так: 1.Да. 2. Вы спросили «почему» и попросили не получать слишком много технических деталей - но, как сказал «yulkes», - потому что в Java вы не можете передавать методы в качестве параметров, поэтому вы должны построить этот класс, и приятно создавать его таким образом , 3. С помощью того, что я подытожил в моем первом абзаце, вы можете кратко прочитать документацию (просто имя функции поиска в Google), а также узнать «Поиск кода Google».

0 голосов
/ 30 января 2010

Когда вы вызываете invokeLater, вы передаете ему экземпляр типа Runnable. Runnable - это интерфейс, который объявляет только один метод public void run (). То, что происходит в строке 1 вашего короткого кода, называется «Анонимный внутренний класс» - вы создаете экземпляр Runnable, который используется только один раз, вы даже не называете его.

InvokeLater получит ваш Runnable, а внутри будет делать что-то вроде

public static void invokeLater(Runnable r) {
    // Wait for the correct time to run this
    r.run()
}

Это означает, что invokeLater решит, когда вызывать метод run, таким образом запустив createAndShowGUI.

Поскольку в Java вы не можете передавать методы в качестве параметров для запуска (пока), вы вынуждены создать этот одноразовый экземпляр Runnable.

...