2010-01-30 3 views
7

У меня есть проблемы с пониманием этого простого кода:Может ли кто-нибудь объяснить мне этот метод разворота javax?

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

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

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

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

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

Благодарим вас, если вы решите помочь мне!

ответ

6

Это anonymous inner class.

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

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

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

+0

Это не «качающаяся нить». Сообщение об отключении события AWT (EDT) вообще не зависит от Swing. 'java.awt.EventQueue.invokeLater' имеет гораздо больше смысла. –

+0

('SwingUtilities.invokeLater' существует только для совместимости с Java 1.1 (заменен Java2 версии 1.2 в 1998 году). –

+0

' SwingUtilities.invokeLater' и 'EventQueue.invokeLater' были введены в 1.2. Они стали эквивалентными в 1.3. Также не рекомендуется. И различие AWT-vs-Swing на самом деле не актуально для начинающего вопроса, поэтому да, EDT можно назвать «нитью Swing». – finnw

11

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

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.

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

+5

On invokeLater: Swing - это однопоточный инструментарий GUI. Существует специальный поток, называемый Thread Dispatch Thread (EDT), который предназначен для отображения и обновления компонентов Swing. invokeLater - это вспомогательный метод, гарантирующий, что любой код, который каким-либо образом изменяет графический интерфейс, только делает это во время работы над этим специальным EDT. Метод invokeLater вызовет код в методе «run» в какой-то момент в разделе «Диспетчер событий». Я бы предположил, что метод createAndShowGUI будет создавать, инициализировать и отображать компоненты, поэтому его нужно запускать только на EDT. – Ash

+0

Спасибо, хорошее объяснение. – danben

0

Когда вы вызываете 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 будет решать, когда для вызова метода запуска, таким образом, работает createAndShowGUI.

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

+0

Вы можете передавать методы, используя 'java.reflect.Method', а затем' myMethod.invoke() ', но это дает гораздо больше беспорядок, чем анонимный класс. – 11684

2

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

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

1

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

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

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

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