2009-12-04 9 views
6

En una aplicación de GUI Java "grave", tendrá modelos detrás de muchos de sus elementos GUI: A DocumentModel respaldando un JEditorPane, por ejemplo, o un ListModel detrás de un JList.¿Está bien cambiar un modelo fuera del hilo de trabajo Swing?

Siempre nos dicen que no hagamos cambios en la GUI desde fuera del hilo de trabajo Swing y le damos SwingUtilities.invoke...() para solucionar eso. Bien, puedo vivir con eso! Sin duda es necesario (y funciona bien) al cambiar los atributos de los componentes de la GUI directamente.

Idealmente, la mayoría de mis cambios GUI-visibles serán a modelos, no a JComponents, de todos modos. Pero debido a que son visibles en la GUI, ¿"cuentan" como cambios en la GUI? Es decir. ¿Cambian los eventos y los oyentes proporcionan el desacoplamiento necesario, o los cambios del modelo también deben ser envueltos en invoke...()?

Probablemente viejo sombrero para profesionales de Swing, pero no pude encontrar ninguna referencia que indique claramente de una forma u otra.

Respuesta

5

Generalmente, el cambio de modelo debe envolverse en invokeLater (...). No hay desacoplamiento en el código del modelo de la mayoría de las clases de swing en las que miré.

Depende de usted crear un modelo que podría contener las llamadas comprobando que las modificaciones de la GUI se realizan en el subproceso Distribuidor de eventos.

+1

-1: ¡No es la respuesta que quería escuchar! (Es una broma, +1) ¡Gracias! –

+1

En cuanto a la ejecución de errores de subprocesos Swing, recomiendo este enlace: http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html El CheckThreadViolationRepaintManager me ha ahorrado mucho tiempo. –

+1

El texto Swing hace * algún * cambio de eventos al EDT. Por supuesto, solo hace un gran desastre. –

2

Si los eventos se activan desde el EDT y actualizan los componentes de Swing, esto será un problema.

En el texto Swing, los eventos pueden o no (!) Ser transferidos al EDT. Esto hace que las pruebas sean difíciles. Como era de esperar, la API no es útil en un entorno multiproceso.

Por lo tanto: más fácil mantener el modelo en el EDT y otros hilos deben pasar mensajes (que implica EventQueue.invokeLater). Alternativamente, puede poner un gran candado alrededor de todo, lo cual es más difícil (y es probable que aún deba pasar cosas al EDT). Intentar la microsincronización es muy difícil.

+1

"la microsincronización es muy difícil". : Estoy totalmente de acuerdo con este punto. Eliminé todas mis palabras clave sincronizadas y comprobé con más cuidado que todas las modificaciones en la GUI (y los modelos de los elementos de la GUI) se realizaron en el EDT. –

+1

Tenía miedo de esto. Significa que mis modelos se vuelven técnicamente parte de la GUI y deben tratarse como parte de ella para este propósito. No parece "limpio" desde un punto de vista de capas/encapsulación, y (esta es mi mayor objeción, por supuesto) ¡es más trabajo! +1, gracias! –

2

Sí, definitivamente está bien.

Si bien es cierto, no debe modificar componentes Swing fuera del EDT. Ciertamente puede hacer cambios en sus modelos fuera del EDT.

Si ha conectado correctamente los modelos a sus componentes Swing, la actualización de la vista y, por lo tanto, la programación de EDT se realizarán casi automáticamente.

Ver: http://java.sun.com/products/jfc/tsc/articles/architecture/#roots

ver la parte sobre el modelo de JavaBeans Evento.

Así es como los modelos comunican su estado cambiado a la GUI de una manera segura EDT. Al crear nuevos componentes de la GUI, debe seguir este patrón de diseño.

También tenga en cuenta la diferencia entre los modelos de estado de GUI y los modelos de datos de aplicación.

Realizar cambios en los modelos desde el EDT aún requiere cuidado. De hecho, la mayoría de los problemas de Swing ocurren cuando el programador está modificando un modelo en el EDT cuando deberían modificarlo desde un hilo separado.(Problema infame de la GUI congelada)

Además, nada de esto impide conocer por completo las típicas dificultades de múltiples subprocesos.

Pero definitivamente puede hacer cambios en un JTableModel desde fuera del EDT.

Cuestiones relacionadas