inactividad el subproceso actual en ejecución durante un máximo de 4 milisegundos. En breve hablaremos sobre 
el por qué de esto. En la línea 61 se evalúa si el elemento del arreglo 

primos

 en el índice actual es 

true

 (y por 

ende, primo). De ser así, en la línea 63 se pasa el índice al método 

publish

 de manera que pueda mostrarse como 

resultado intermedio en la GUI, y en la línea 64 se incrementa el número de primos encontrados. En las líneas 66 
y 67 se establecen en 

false

 todos los múltiplos del índice actual, para indicar que no son primos. Cuando se ha 

recorrido todo el arreglo 

boolean

, el número de primos encontrados se devuelve en la línea 72. 

En las líneas 76 a 80 se declara el método 

process

, el cual se ejecuta en el subproceso de despachamiento 

de eventos y recibe su argumento 

valsPublicados

 del método 

publish

. El paso de valores entre 

publish

 en 

el subproceso trabajador y 

process

 en el subproceso de despachamiento de eventos es asíncrono; 

process

 no se 

invoca necesariamente para cada una de las llamadas a 

publish

. Todos los objetos 

Integer

 publicados desde la 

última llamada a 

publish

 se reciben como un objeto 

List

, a través del método 

process

. En las líneas 78 y 79 

se itera a través de esta lista y se muestran los valores publicados en un objeto 

JTextArea

. Como el cálculo en el 

método

doInBackground

 progresa rápidamente, publicando valores con frecuencia, las actualizaciones al objeto 

JTextArea

 se pueden apilar en el subproceso de despachamiento de eventos, lo que puede provocar que la GUI 

tenga una respuesta lenta. De hecho, al buscar un número sufi cientemente largo de primos, el subproceso de 
despachamiento de eventos puede llegar a recibir tantas peticiones en una rápida sucesión para actualizar el objeto 

JTextArea

, que el subproceso se quedará sin memoria en su cola de eventos. Ésta es la razón por la cual pusi-

mos al subproceso trabajador en inactividad durante unos cuantos milisegundos, entre cada llamada potencial a 

publish

. Se reduce la velocidad del cálculo lo sufi ciente como para permitir que el subproceso despachador de 

eventos se mantenga a la par con las peticiones para actualizar el objeto 

JTextArea

 con nuevos números primos, 

lo cual permite a la GUI actualizarse de manera uniforme y así puede permanecer con una capacidad de respuesta 
relativamente inmediata.

En las líneas 83 a 106 se defi ne el método 

done

. Cuando el cálculo termina o se cancela, el método 

done

habilita el botón 

Obtener primos

 y deshabilita el botón 

Cancelar

 (líneas 85 y 86). En la línea 92 se obtiene el 

valor de retorno (el número de primos encontrados) del método 

doInBackground

. En las líneas 94 a 103 se 

atrapan las excepciones lanzadas por el método 

get

 y se muestra un mensaje de error apropiado en el objeto 

estadoJLabel

. Si no ocurren excepciones, en la línea 105 se establece el objeto 

estadoJLabel

 para indicar el 

número de primos encontrados. 

En las líneas 109 a 112 se defi ne el método 

publicdetenerCalculo

, el cual se invoca cuando el usua-

rio hace clic en el botón 

Cancelar

. Este método establece la bandera 

detenido

 en la línea 111, de forma que 

doInBackground

 pueda regresar sin terminar su cálculo la próxima vez que evalúe esta bandera. Aunque 

Swing-

Worker

 cuenta con un método 

cancel

, este método simplemente llama al método 

interrupt

 de 

Thread

 en el 

subproceso trabajador. Al utilizar la bandera 

boolean

 en vez del método 

cancel

, podemos detener el cálculo 

limpiamente, devolver un valor de 

doInBackground

 y asegurar que se haga una llamada al método 

done

, aun si 

el cálculo no se ejecutó hasta completarse, sin el riesgo de lanzar una excepción 

InterruptedException

 asociada 

con la acción de interrumpir el subproceso trabajador.

La clase 

BuscarPrimos

 (fi gura 23.28) muestra un objeto 

JTextField

 que permite al usuario escribir un 

número, un objeto 

JButton

 para empezar a buscar todos los números primos menores que ese número, y 

un objeto 

JTextArea

 para mostrar los números primos. Un objeto 

JButton

 permite al usuario cancelar el cálcu-

lo, y un objeto 

JProgressBar

 indica el progreso del cálculo. El constructor de 

BuscarPrimos

 (líneas 32 a 125) 

inicializa estos componentes y los muestra en un objeto 

JFrame

, usando el esquema 

BorderLayout

.

En las líneas 42 a 94 se registra el manejador de eventos para el objeto 

obtenerPrimosJButton

. Cuando el 

usuario hace clic en este objeto 

JButton

, en las líneas 47 a 49 se restablece el objeto 

JProgressBar

 y se borran los 

objetos

mostrarPrimosJTextArea

 y 

estadoJLabel

. En las líneas 53 a 63 se analiza el valor en el objeto 

Jtext-

Field

 y se muestra un mensaje de error si el valor no es un entero. En las líneas 66 a 68 se construye un nuevo 

objeto

CalculadoraPrimos

, el cual recibe como argumentos el entero que escribió el usuario, el objeto 

mos-

trarPrimosJTextArea

 para mostrar los números primos, el objeto 

estadoJLabel

 y los dos objetos 

JButton

.

En las líneas 71 a 85 se registra un objeto 

PropertyChangeListener

 para el nuevo objeto 

Calculadora-

Primos

, mediante el uso de una clase interna anónima. 

PropertyChangeListener

 es una interfaz del paquete 

java.beans

 que defi ne un solo método, 

propertyChange

. Cada vez que se invoca el método 

setProgress

 en 

un objeto 

CalculadoraPrimos

, este objeto genera un evento 

PropertyChangeEvent

 para indicar que la pro-

piedad de progreso ha cambiado. El método 

propertyChange

 escucha estos eventos. En la línea 78 se evalúa si 

un evento 

PropertyChangeEvent

 dado indica un cambio en la propiedad de progreso. De ser así, en la línea 80 

se obtiene el nuevo valor de la propiedad y en la línea 81 se actualiza el objeto 

JProgressBar

 con el nuevo valor 

23.11 Subprocesamiento múltiple con GUIs 

979

23_MAQ_CAP_23_DEITEL.indd979

4/19/081:34:00AM