2010-01-30 9 views
7

tengo problemas para entender este código simple:¿Alguien puede explicarme este método de oscilación de javax?

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

Puede alguien por favor me explique cómo funciona (en términos sencillos porque yo soy muy novato)? Este código corto es una parte de este larger code.

Para ser más específico, tengo las siguientes preguntas:

  1. significa "public void run" definir un nuevo método? Si es el caso, ¿por qué se define dentro de otro método (ver "código más grande" para referencia)?
  2. Si "public void run" define un nuevo método, ¿cuál es el motivo para definir un método que contenga solo una línea de código (createAndShowGUI)?
  3. ¿Qué significa "invokeLater"? Esta es en realidad la pregunta más complicada para mí.

Me gustaría destacar una vez más que soy un novato y el uso de palabras "especiales" y "técnicas" producirá aún más preguntas.

¡Gracias de antemano, si decides ayudarme!

Respuesta

6

Es un anonymous inner class.

está definiendo tres cosas:

  • Una nueva clase
  • un método llamado run dentro de esa clase
  • Una nueva instancia de esa clase

En este ejemplo alguna operación (createAndShowGUI()) necesita ejecutarse en el hilo Swing. No puede "saltar" a otro hilo en el medio de una llamada a un método, por lo que en su lugar está colocando un objeto (la nueva instancia que creó) en una cola. Cuando el hilo Swing esté listo, eliminará ese objeto de la cola y llamará a su método run, que a su vez llama al createAndShowGUI. Ahora todo sucede en el hilo correcto.

+0

No es "el hilo Swing". El AWT Event Dispatch Thread (EDT) no depende de Swing en absoluto. 'java.awt.EventQueue.invokeLater' tiene mucho más sentido. –

+0

('SwingUtilities.invokeLater' solo existe para compatibilidad con Java 1.1 (reemplazado por Java2 versión 1.2 en 1998). –

+0

' SwingUtilities.invokeLater' y 'EventQueue.invokeLater' se introdujeron en 1.2. Se convirtieron en equivalentes en 1.3. Ninguno de los dos está en desuso. Y la distinción AWT-vs-Swing no es realmente relevante para una pregunta para principiantes, así que sí, el EDT se puede llamar "el hilo Swing". – finnw

11

La respuesta más corta que puedo dar es:

Runnable es una interfaz en Java que representa un tipo que define un método run. Cualquier clase que implemente esta interfaz debe proporcionar una implementación para run. Runnable s representan tareas que deben ser ejecutadas por otras partes de su sistema. Thread es un conocido Runnable.

Cuando tiene un código que se parece a new InterfaceName() { //implementation }, se denomina clase anónima. El objetivo de una clase anónima es crear una clase única implementando el tipo de interfaz. Esta clase no tiene nombre, y como tal, nunca más podemos referirnos a ella. Solo se usa aquí.

sin saber mucho sobre Swing, parece que SwingUtilities.invokeLater() acepta un Runnable y ... bueno, supongo que lo invoca más tarde (cuánto tiempo más tarde, probablemente se describe en el JavaDocs).Pero, la razón por la que definiría run aquí como simplemente otra invocación de método es que algún código dentro de SwingUtilities va a llamar al método run en este Runnable; de hecho, todo lo que posiblemente pueda saber sobre cualquier Runnable es que define un método con la firma public void run(), porque ese es el único método definido en la interfaz Runnable.

Bueno, supongo que no era demasiado corto después de todo.

+5

En invokeLater: Swing es un kit de herramientas GUI de subproceso único. Hay un hilo especial llamado Subproceso Despacho de evento (EDT) que está dedicado a mostrar y actualizar componentes de Swing. invokeLater es un método de ayuda para garantizar que cualquier código que modifique la GUI de alguna manera solo lo haga mientras se ejecuta en este EDT especial. El método invokeLater llamará al código en el método "ejecutar" en algún momento en el futuro en el hilo de envío del evento. Supongo que el método createAndShowGUI creará, inicializará y mostrará componentes, por lo tanto, solo se debe ejecutar en el EDT. – Ash

+0

Gracias, buena explicación. – danben

0

Cuando llama a invocarLater lo está pasando una instancia de tipo ejecutable. Runnable es una interfaz que declara solo un método "public void run()". Lo que sucede en la línea 1 de su código corto, se llama "Clase interna anónima": está creando una instancia de Runnable que se usa una sola vez, ni siquiera la está nombrando.

invokeLater recibirá su Ejecutable, y en el interior va a hacer algo así como

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

Esto significa invokeLater decidirá cuándo llamar al método de ejecución, lo que se corre createAndShowGUI.

Porque en Java no puede pasar métodos como parámetros para ejecutar (todavía), se ve obligado a crear esta instancia de Runnable de un solo uso.

+0

Puede pasar métodos, usando 'java.reflect.Method', y luego' myMethod.invoke() ', pero esto da mucha más confusión que una clase anónima. – 11684

2

Si bien es así como Swing generalmente crea una GUI, lo único que hacen es decir "hazlo así, explicaremos por qué más adelante". Y creo que tienen razón, porque los detalles son algo complicados y no útiles para un principiante. Pero de todos modos:

invokeLater lanza un hilo que ejecutará una clase Runnable más tarde. La clase ejecutable se crea ad hoc según lo mencionado por finnw a través de new Runnable { [..] } y debe especificar un método public void run() de acuerdo con la interfaz Runnable. En este caso, todo lo que hace es ejecutar el método createAndShowGUI.

1

Este código hace que una función (createAndShowGUI()) sea llamada en otra conversación. En caso de que no sepa qué hilo es, mejor lea sobre él, pero de todos modos, piénselo como código que se realiza al mismo tiempo que se realiza otro código. El otro código serán las líneas que siguen a esta llamada a Invoke(). Esto es muy común en las aplicaciones gráficas, el código se ejecuta para actualizar el gráfico, mientras que otro código responde a las acciones del usuario. Dicho esto, no me he molestado en leer la documentación sobre InvokeLater() y no he escrito demasiado Java en mi vida. Como dijo 'LumpN' - 'así es como Swing normalmente crea una GUI'.

Lo más extraño (para un novato) es que el parámetro invokeLater() se define de forma anónima - 'dentro del código'. En realidad, es algo bueno ya que esta clase no tiene nada de nuevo. Todas las otras respuestas han explicado lo anónimo.

so: 1.yes. 2. Preguntaste por qué y le pediste que no obtuvieras demasiados detalles técnicos, pero como dice 'yulkes', porque en Java no puedes pasar los métodos como parámetros, así que debes construir esta clase, y es bueno construirlo como esta. 3. Con lo que he resumido en mi primer párrafo, puede leer brevemente la documentación (solo el nombre de la función de búsqueda en Google), también obtener la 'búsqueda de código de Google'.

Cuestiones relacionadas