Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
J A p p l e t : representa una ventana grfica incluida en una pgina html para que un navegador se haga
cargo de ella. Se estudia este elemento en detalle en el captulo correspondiente.
J F r a m e : representa una ventana grfica completa y plenamente funcional. Dispone de una barra de
ttulo, de un men sistema y de un borde. Puede fcilmente acoger un men, y por supuesto, es el elemento que vamos a emplear en la mayora de los casos.
1. Las ventanas
La clase J F r a m ees el elemento indispensable de toda aplicacin grfica. Como en el caso de una clase normal, debemos crear una instancia, modificar eventualmente las propiedades y utilizar los mtodos. A continuacin est el cdigo de la primera aplicacin grfica.
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887
1/23
24/4/2014
Es sencillo de usar y muy eficaz. De hecho, es tan eficaz que no se puede parar la aplicacin. En efecto, incluso si el usuario cierra la ventana, este cierre no provoca la supresin de la instancia de la J F r a m ede la memoria. La nica solucin para detener la aplicacin es apagar la mquina virtual Java con la combinacin de teclas [Ctrl] C. Ante esto, se recomienda proporcionar otra solucin para detener ms fcilmente la ejecucin de la aplicacin, esto es, junto con el cierre de la ventana. Una primera solucin consiste en gestionar los eventos que se producen en el momento del cierre de la ventana, y en uno de ellos, provocar la detencin de la aplicacin. Se estudiar esta solucin en el prrafo dedicado a la gestin de los eventos. La segunda solucin utiliza comportamientos predefinidos para el cierre de la ventana. Estos comportamientos estn determinados por el mtodo s e t D e f a u l t C l o s e O p e r a t i o n . Se definen varias constantes para determinar la accin emprendida al cierre de la ventana.
H I D E _ O N _ C L O S E : con esta opcin la ventana simplemente queda oculta como consecuencia de una llamada a su mtodo s e t V i s i b l e ( f a l s e ) .
La clase J F r a m ese encuentra al final de una jerarqua de clases bastante importante e implementa numerosas interfaces. Por eso, dispone de varios mtodos y atributos.
La meta de este libro no es retomar toda la documentacin del JDK, y por eso, no recorre todos los mtodos disponibles sino sencillamente los ms utilizados segn las necesidades. Sin embargo puede resultar interesante hojear la documentacin antes de lanzarse al diseo de un mtodo para determinar si lo que queremos disear no ha sido ya previsto por los diseadores de Java. Ahora que somos capaces de visualizar una ventana, el grueso del trabajo va a consistir en aadir un contenido a la ventana. Antes de poder aadir algo a una ventana, hay que entender bien su estructura que resulta relativamente compleja. Un objeto J F r a m e se compone de varios elementos superpuestos que tienen cada uno un papel muy especfico en la gestin de la ventana.
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887
2/23
24/4/2014
El elemento R o o t P a n e corresponde al contenedor de los otros tres elementos. El elemento L a y e r e d P a n ees el responsable de la gestin de la posicin de los elementos tanto en los ejes X e Y como en el eje Z lo que permite la superposicin de diferentes elementos. El elemento C o n t e n t P a n ees el contenedor bsico de todos los elementos aadidos en la ventana. A l vamos a confiarle, por esta razn, los diferentes componentes de la interfaz de la aplicacin. Por encima delC o n t e n t P a n e , se superpone el G l a s s P a n ecomo se puede hacer con un cristal sobre una foto. De hecho, presenta muchas similitudes con el cristal. Es transparente por defecto. Lo dibujado en el G l a s s P a n eesconde los dems elementos. Es capaz de interceptar los eventos relacionados con el ratn antes de que stos hayan alcanzado los otros componentes. De todos estos elementos, es sin duda el C o n t e n t P a n eel que vamos a utilizar regularmente. Podemos acceder a l a travs del mtodo g e t C o n t e n t P a n ede la clase J F r a m e . Es tcnicamente posible ubicar componentes directamente en el objeto C o n t e n t P a n epero es una prctica que Sun no aconseja. Se prefiere intercalar un contenedor intermediario que acoger los componentes y ubicarlo en el C o n t e n t P a n e . Para este papel, se suele utilizar el componente J P a n e l . Por lo tanto, el escenario clsico de diseo de una interfaz grfica consiste en crear los diferentes componentes, y luego ubicarlos en un contenedor, y por fin, situar este contenedor en elC o n t e n t P a n e de la ventana. El ejemplo siguiente pone esto en aplicacin al crear una interfaz usuario compuesta por tres botones.
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . G r a p h i c s ; i m p o r tj a v a x . s w i n g . J B u t t o n ; i m p o r tj a v a x . s w i n g . J F r a m e ; i m p o r tj a v a x . s w i n g . J P a n e l ; p u b l i cc l a s sM a i n{
p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) { / /c r e a c i nd el av e n t a n a J F r a m ev e n t a n a ; v e n t a n a = n e wJ F r a m e ( ) ; v e n t a n a . s e t T i t l e ( " p r i m e r av e n t a n ae nJ A V A " ) ; v e n t a n a . s e t B o u n d s ( 0 , 0 , 3 0 0 , 1 0 0 ) ; v e n t a n a . s e t D e f a u l t C l o s e O p e r a t i o n ( J F r a m e . E X I T _ O N _ C L O S E ) ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 3/23
24/4/2014
/ /c r e a c i nd el o st r e sb o t o n e s J B u t t o nb 1 , b 2 , b 3 ; b 1 = n e wJ B u t t o n ( " R o j o " ) ; b 2 = n e wJ B u t t o n ( " V e r d e " ) ; b 3 = n e wJ B u t t o n ( " A z u l " ) ; / /c r e a c i nd e lc o n t e n e d o ri n t e r m e d i a r i o J P a n e lp a n o ; p a n o = n e wJ P a n e l ( ) ; / /a a d i d od el o sb o t o n e se ne lc o n t e n e d o ri n t e r m e d i a r i o p a n o . a d d ( b 1 ) ; p a n o . a d d ( b 2 ) ; p a n o . a d d ( b 3 ) ; / /a a d i d od e lc o n t e n e d o ri n t e r m e d i a r i oe ne lC o n t e n t P a n e v e n t a n a . g e t C o n t e n t P a n e ( ) . a d d ( p a n o ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } } Al ejecutarse, este cdigo muestra la ventana siguiente:
La siguiente etapa de nuestro anlisis nos va a permitir determinar lo que debe hacer la aplicacin cuando el usuario va a hacer clic en uno de los botones.
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887
4/23
24/4/2014
La primera parte del nombre representa la categora de eventos que los objetos, que implementan esta interfaz, pueden gestionar. El nombre siempre se termina por L i s t e n e r . Por ejemplo, tenemos la interfaz M o u s e M o t i o n L i s t e n e rque corresponde a los eventos activados por los movimientos del ratn, o la interfaz A c t i o n L i s t e n e rque corresponde a un clic en un botn. En cada una de estas interfaces encontramos las firmas de los diferentes mtodos asociados a cada evento.
p u b l i ci n t e r f a c eM o u s e M o t i o n L i s t e n e r e x t e n d sE v e n t L i s t e n e r { v o i dm o u s e D r a g g e d ( M o u s e E v e n te ) ; v o i dm o u s e M o v e d ( M o u s e E v e n te ) ; } Cada uno de estos mtodos espera como argumento un objeto que representa el propio evento. Este objeto es creado automticamente en el momento de la activacin del evento y luego es pasado como argumento al mtodo encargado de gestionar el evento en el escuchador de evento. En general, contiene informacin adicional relativa al evento y es especfico para cada tipo de evento. Necesitamos crear clases que implementen estas interfaces. Desde este punto de vista, tenemos una multitud de posibilidades: Crear una clase "normal" que implemente la interfaz. Implementar la interfaz en una clase ya existente. Crear una clase interna que implemente la interfaz. Crear una clase interna annima que implemente la interfaz. En algunos casos, quiz sea necesario no gestionar todos los eventos presentes en la interfaz. Sin embargo, es obligatorio escribir todos los mtodos exigidos por la interfaz incluso si varios de ellos no contienen ningn cdigo. Esto puede perjudicar la legibilidad del cdigo. Para paliar este problema, Java propone para casi cada interfaz X X X X X L i s t e n e r una clase abstracta correspondiente que implementa ya la interfaz, y que contiene los mtodos exigidos por la interfaz. Estos mtodos no contienen cdigo alguno ya que el tratamiento de cada evento debe ser especfico a cada aplicacin. Estas clases emplean la misma convencin de nombramiento que las interfaces, excepto que se sustituye L i s t e n e rpor A d a p t e r . Tenemos por ejemplo la clase M o u s e M o t i o n A d a p t e rque implementa la interfaz M o u s e M o t i o n L i s t e n e r . Se pueden utilizar estas clases de varias maneras: Crear una clase "normal" que herede de una de estas clases. Crear una clase interna que herede de una de estas clases. Crear una clase interna annima que herede de una de estas clases. El uso de una clase interna annima es la solucin que ms se utiliza con el pequeo inconveniente de tener una sintaxis difcil de leer si uno no est acostumbrado. Para aclarar todo esto, vamos a ilustrar cada una de estas posibilidades con un pequeo ejemplo. Este ejemplo nos va a permitir terminar correctamente la aplicacin en el momento del cierre de la ventana principal al llamar el mtodo S y s t e m . e x i t ( 0 ) . Se debe llamar este mtodo durante la deteccin del cierre de la ventana. Para esto, debemos gestionar los eventos relacionados con la ventana y en particular, el evento w i n d o w C l o s i n g que es activado en el momento en el cual el usuario pide el cierre de la ventana por el men sistema. La interfaz W i n d o w L i s t e n e rest perfectamente adaptada para este tipo de trabajo. La base de nuestro trabajo se compone de las dos clases siguientes:
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 5/23
24/4/2014
p a c k a g ee s . e n i ; p u b l i cc l a s sM a i n{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) { / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } } Si ejecutamos este cdigo, la ventana aparece pero ya no es posible cerrarla y an menos detener la aplicacin. Veamos ahora cmo remediar este problema con las diferentes soluciones mencionadas ms arriba.
24/4/2014
p u b l i cc l a s sE s c u c h a d o r V e n t a n ai m p l e m e n t sW i n d o w L i s t e n e r{ p u b l i cv o i dw i n d o w A c t i v a t e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w C l o s e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w C l o s i n g ( W i n d o w E v e n ta r g 0 ) { S y s t e m . e x i t ( 0 ) ; } p u b l i cv o i dw i n d o w D e a c t i v a t e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w D e i c o n i f i e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w I c o n i f i e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w O p e n e d ( W i n d o w E v e n ta r g 0 ) { } }
p a c k a g ee s . e n i ; p u b l i cc l a s sM a i n{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) { / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /c r e a c i nd eu n ai n s t a n c i ad el ac l a s ee n c a r g a d a / /d eg e s t i o n a rl o se v e n t o s E s c u c h a d o r V e n t a n ae v ; e v = n e wE s c u c h a d o r V e n t a n a ( ) ; / /r e f e r e n c i a c i nd ee s t ai n s t a n c i ad ec l a s e / /c o m oe s c u c h a d o rd ee v e n t op a r al av e n t a n a v e n t a n a . a d d W i n d o w L i s t e n e r ( e v ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } }
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . e v e n t . W i n d o w E v e n t ; i m p o r tj a v a . a w t . e v e n t . W i n d o w L i s t e n e r ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 7/23
24/4/2014
24/4/2014
{ / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } } Con esta solucin, el cdigo se centraliza en una nica clase. Si hay que gestionar varios eventos, esta clase va a contener una multitud de mtodos.
24/4/2014
p u b l i cc l a s sE s c u c h a d o r V e n t a n ai m p l e m e n t sW i n d o w L i s t e n e r { p u b l i cv o i dw i n d o w A c t i v a t e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w C l o s e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w C l o s i n g ( W i n d o w E v e n ta r g 0 ) { S y s t e m . e x i t ( 0 ) ; } p u b l i cv o i dw i n d o w D e a c t i v a t e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w D e i c o n i f i e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w I c o n i f i e d ( W i n d o w E v e n ta r g 0 ) { } p u b l i cv o i dw i n d o w O p e n e d ( W i n d o w E v e n ta r g 0 ) { } } } p a c k a g ee s . e n i ; p u b l i cc l a s sM a i n{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) { / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } } Con esta solucin, se reparten las responsabilidades entre varias clases, pero a cambio, vamos a obtener una multiplicacin del nmero de clases.
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . e v e n t . W i n d o w E v e n t ; i m p o r tj a v a . a w t . e v e n t . W i n d o w L i s t e n e r ; i m p o r tj a v a x . s w i n g . J B u t t o n ; i m p o r tj a v a x . s w i n g . J F r a m e ; i m p o r tj a v a x . s w i n g . J P a n e l ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 10/23
24/4/2014
24/4/2014
{ / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } } El nico reproche que se le pueda hacer a esta solucin reside en la relativa complejidad de la sintaxis. Los comentarios entre las diferentes lneas ofrecen una ayuda valiosa para no perderse entre las llaves y parntesis. Por el contrario, hay un reproche global que se les puede hacer a todas estas soluciones: para un nico mtodo realmente til, tenemos que escribir siete. Para evitar este cdigo intil, podemos trabajar con una clase que implemente ya la interfaz correcta y volver a definir nicamente los mtodos que nos interesan.
p a c k a g ee s . e n i ; p u b l i cc l a s sM a i n{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) { / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /c r e a c i nd eu n ai n s t a n c i ad el ac l a s ee n c a r g a d a / /d eg e s t i o n a rl o se v e n t o s E s c u c h a d o r V e n t a n ae v ; e v = n e wE s c u c h a d o r V e n t a n a ( ) ; / /r e f e r e n c i a c i nd ee s t ai n s t a n c i ad ec l a s e / /c o m oe s c u c h a d o rd ee v e n t op a r al av e n t a n a v e n t a n a . a d d W i n d o w L i s t e n e r ( e v ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } }
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 12/23
24/4/2014
24/4/2014
{ / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } }
Crear una clase interna annima que herede de una clase XXXXAdapter
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . e v e n t . W i n d o w E v e n t ; i m p o r tj a v a . a w t . e v e n t . W i n d o w L i s t e n e r ; i m p o r tj a v a x . s w i n g . J B u t t o n ; i m p o r tj a v a x . s w i n g . J F r a m e ; i m p o r tj a v a x . s w i n g . J P a n e l ; p u b l i cc l a s sP a n t a l l ae x t e n d sJ F r a m e { p u b l i cP a n t a l l a ( ) { s e t T i t l e ( " p r i m e r av e n t a n ae nJ A V A " ) ; s e t B o u n d s ( 0 , 0 , 3 0 0 , 1 0 0 ) ; s e t D e f a u l t C l o s e O p e r a t i o n ( J F r a m e . D O _ N O T H I N G _ O N _ C L O S E ) ; / /c r e a c i nd el o st r e sb o t o n e s J B u t t o nb 1 , b 2 , b 3 ; b 1 = n e wJ B u t t o n ( " R o j o " ) ; b 2 = n e wJ B u t t o n ( " V e r d e " ) ; b 3 = n e wJ B u t t o n ( " A z u l " ) ; / /c r e a c i nd e lc o n t e n e d o ri n t e r m e d i a r i o J P a n e lp a n o ; p a n o = n e wJ P a n e l ( ) ; / /a a d i d od el o sb o t o n e se ne lc o n t e n e d o ri n t e r m e d i a r i o p a n o . a d d ( b 1 ) ; p a n o . a d d ( b 2 ) ; p a n o . a d d ( b 3 ) ; / /a a d i d od e lc o n t e n e d o ri n t e r m e d i a r i o / /e ne lC o n t e n t P a n e g e t C o n t e n t P a n e ( ) . a d d ( p a n o ) ; / /c r e a c i nd eu n ai n s t a n c i ad eu n ac l a s ea n n i m a / /e n c a r g a d ad eg e s t i o n a rl o se v e n t o s a d d W i n d o w L i s t e n e r ( n e wW i n d o w A d a p t e r ( ) / /p r i n c i p i od el ad e f i n i c i nd el ac l a s e { p u b l i cv o i dw i n d o w C l o s i n g ( W i n d o w E v e n ta r g 0 ) { S y s t e m . e x i t ( 0 ) ; } }/ /f i nd el ad e f i n i c i nd el ac l a s e ) ;/ /f i nd el al l a m a d aa lm t o d oa d d W i n d o w L i s t e n e r } / /f i nd e lc o n s t r u c t o r } / /f i nd el ac l a s eP a n t a l l a p a c k a g ee s . e n i ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 14/23
24/4/2014
p u b l i cc l a s sM a i n{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ) { / /c r e a c i nd el av e n t a n a P a n t a l l av e n t a n a ; v e n t a n a = n e wP a n t a l l a ( ) ; / /v i s u a l i z a c i nd el av e n t a n a v e n t a n a . s e t V i s i b l e ( t r u e ) ; } } Por supuesto, esta solucin es la ms ahorradora en nmero de lneas y tambin la que utilizan numerosas herramientas de desarrollo que generan automticamente cdigo. La relativa complejidad del cdigo puede inquietar cuando uno no est acostumbrado a ello. Hasta ahora, tenemos una fuente de evento y un escuchador para esta fuente de evento. En algunos casos, podemos estar en la situacin de tener varias fuentes de eventos y desear utilizar el mismo escuchador o tener una fuente de evento y avisar varios escuchadores. La situacin clsica en la cual tenemos varias fuentes de eventos y un nico escuchador ocurre cuando proporcionamos al usuario varias soluciones para lanzar la ejecucin de una misma accin (men y barra de herramientas o botones). Sea cul sea el medio utilizado para lanzar la accin, el cdigo a ejecutar sigue siendo el mismo. En este supuesto, podemos emplear el mismo escuchador para las dos fuentes de eventos. Para ilustrar esto, vamos a aadir un men a la aplicacin y hacer de tal manera que la utilizacin del men o de uno de los botones ejecute la misma accin al modificar el color de fondo correspondiente al botn o al men usado. Como debemos utilizar el mismo escuchador para dos fuentes de eventos, es preferible utilizar una clase interna para la creacin del escuchador. A continuacin, presentamos el cdigo correspondiente.
24/4/2014
/ /c r e a c i nd el o st r e se s c u c h a d o r e s E s c u c h a d o r R o j oe s c R ; E s c u c h a d o r V e r d ee s c V ; E s c u c h a d o r A z u le s c A ; e s c R = n e wE s c u c h a d o r R o j o ( ) ; e s c V = n e wE s c u c h a d o r V e r d e ( ) ; e s c A = n e wE s c u c h a d o r A z u l ( ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d ab o t n b t n R o j o . a d d A c t i o n L i s t e n e r ( e s c R ) ; b t n V e r d e . a d d A c t i o n L i s t e n e r ( e s c V ) ; b t n A z u l . a d d A c t i o n L i s t e n e r ( e s c A ) ; / /C r e a c i nd e lm e n J M e n u B a rb a r r a M e n u ; b a r r a M e n u = n e wJ M e n u B a r ( ) ; J M e n um n u C o l o r e s ; m n u C o l o r e s = n e wJ M e n u ( " C o l o r e s " ) ; b a r r a M e n u . a d d ( m n u C o l o r e s ) ; J M e n u I t e mm n u R o j o , m n u V e r d e , m n u A z u l ; m n u R o j o = n e wJ M e n u I t e m ( " R o j o " ) ; m n u V e r d e = n e wJ M e n u I t e m ( " V e r d e " ) ; m n u A z u l = n e wJ M e n u I t e m ( " A z u l " ) ; m n u C o l o r e s . a d d ( m n u R o j o ) ; m n u C o l o r e s . a d d ( m n u V e r d e ) ; m n u C o l o r e s . a d d ( m n u A z u l ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d am e n / /(l o sm i s m o sq u ep a r al o sb o t o n e s) m n u R o j o . a d d A c t i o n L i s t e n e r ( e s c R ) ; m n u V e r d e . a d d A c t i o n L i s t e n e r ( e s c V ) ; m n u A z u l . a d d A c t i o n L i s t e n e r ( e s c A ) ; / /a a d i d od e lm e n e nl av e n t a n a s e t J M e n u B a r ( b a r r a M e n u ) ; / /c r e a c i nd e lc o n t e n e d o ri n t e r m e d i a r i o p a n o = n e wJ P a n e l ( ) ; / /a a d i d od el o sb o t o n e se ne lc o n t e n e d o ri n t e r m e d i a r i o p a n o . a d d ( b t n R o j o ) ; p a n o . a d d ( b t n V e r d e ) ; p a n o . a d d ( b t n A z u l ) ; / /a a d i d od e lc o n t e n e d o ri n t e r m e d i a r i o / /e ne lC o n t e n t P a n e g e t C o n t e n t P a n e ( ) . a d d ( p a n o ) ; / /c r e a c i nd eu n ai n s t a n c i ad eu n ac l a s ea n n i m a / /e n c a r g a d ad eg e s t i o n a rl o se v e n t o sd el av e n t a n a a d d W i n d o w L i s t e n e r ( n e wW i n d o w A d a p t e r ( ) { p u b l i cv o i dw i n d o w C l o s i n g ( W i n d o w E v e n ta r g 0 ) { S y s t e m . e x i t ( 0 ) ; } } ) ; } p u b l i cc l a s sE s c u c h a d o r R o j oi m p l e m e n t sA c t i o n L i s t e n e r { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n ta r g 0 ) { p a n o . s e t B a c k g r o u n d ( C o l o r . R E D ) ; } } p u b l i cc l a s sE s c u c h a d o r V e r d ei m p l e m e n t sA c t i o n L i s t e n e r { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n ta r g 0 )
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 16/23
24/4/2014
{ p a n o . s e t B a c k g r o u n d ( C o l o r . G R E E N ) ; } } p u b l i cc l a s sE s c u c h a d o r A z u li m p l e m e n t sA c t i o n L i s t e n e r { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n ta r g 0 ) { p a n o . s e t B a c k g r o u n d ( C o l o r . B L U E ) ; } } } En este cdigo, tenemos nuestras tres clases escuchador que son muy similares. Con un pequeo truco, vamos a poder simplificar el cdigo para obtener una sola clase escuchador para los tres botones. Se llamar al mismo mtodo a c t i o n P e r f o r m e dcon un clic en cualquiera de los botones. La eleccin de la accin a ejecutar se har en el interior de este mtodo. Para esto, vamos a utilizar el parmetro A c t i o n E v e n tfacilitado a este mtodo. ste permite obtener una referencia sobre el objeto al origen del evento a travs del mtodo g e t S o u r c e . A continuacin se presenta el cdigo simplificado:
24/4/2014
b a r r a M e n u = n e wJ M e n u B a r ( ) ; J M e n um n u C o l o r e s ; m n u C o l o r e s = n e wJ M e n u ( " C o l o r e s " ) ; b a r r a M e n u . a d d ( m n u C o l o r e s ) ; m n u R o j o = n e wJ M e n u I t e m ( " R o j o " ) ; m n u V e r d e = n e wJ M e n u I t e m ( " V e r d e " ) ; m n u A z u l = n e wJ M e n u I t e m ( " A z u l " ) ; m n u C o l o r e s . a d d ( m n u R o j o ) ; m n u C o l o r e s . a d d ( m n u V e r d e ) ; m n u C o l o r e s . a d d ( m n u A z u l ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d am e n / /(e lm i s m oq u ep a r al o sb o t o n e s) m n u R o j o . a d d A c t i o n L i s t e n e r ( e c ) ; m n u V e r d e . a d d A c t i o n L i s t e n e r ( e c ) ; m n u A z u l . a d d A c t i o n L i s t e n e r ( e c ) ; / /a a d i d od e lm e n e nl av e n t a n a s e t J M e n u B a r ( b a r r a M e n u ) ; / /c r e a c i nd e lc o n t e n e d o ri n t e r m e d i a r i o p a n o = n e wJ P a n e l ( ) ; / /a a d i d od el o sb o t o n e se ne lc o n t e n e d o ri n t e r m e d i a r i o p a n o . a d d ( b t n R o j o ) ; p a n o . a d d ( b t n V e r d e ) ; p a n o . a d d ( b t n A z u l ) ; / /a a d i d od e lc o n t e n e d o ri n t e r m e d i a r i oe ne lC o n t e n t P a n e g e t C o n t e n t P a n e ( ) . a d d ( p a n o ) ; / /c r e a c i nd eu n ai n s t a n c i ad eu n ac l a s ea n n i m a / /e n c a r g a d ad eg e s t i o n a rl o se v e n t o s a d d W i n d o w L i s t e n e r ( n e wW i n d o w A d a p t e r ( ) { p u b l i cv o i dw i n d o w C l o s i n g ( W i n d o w E v e n ta r g 0 ) { S y s t e m . e x i t ( 0 ) ; } } ) ; } p u b l i cc l a s sE s c u c h a d o r C o l o ri m p l e m e n t sA c t i o n L i s t e n e r { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n ta r g 0 ) { i f( a r g 0 . g e t S o u r c e ( ) = = b t n R o j o|a r g 0 . g e t S o u r c e ( ) = = m n u R o j o ) { p a n o . s e t B a c k g r o u n d ( C o l o r . R E D ) ; } i f( a r g 0 . g e t S o u r c e ( ) = = b t n V e r d e|a r g 0 . g e t S o u r c e ( ) = = m n u V e r d e ) { p a n o . s e t B a c k g r o u n d ( C o l o r . G R E E N ) ; } i f( a r g 0 . g e t S o u r c e ( ) = = b t n A z u l|a r g 0 . g e t S o u r c e ( ) = = m n u A z u l ) { p a n o . s e t B a c k g r o u n d ( C o l o r . B L U E ) ; } } } } Hay que sealar que para que funcione esta solucin, los objetos fuente de eventos deben ser accesibles desde la clase escuchador de eventos. Por lo tanto, la declaracin de los botones y de los
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 18/23
24/4/2014
elementos de men ha sido desplazada al nivel de la propia clase y no al del constructor como era el caso en la versin anterior. Esta solucin es posible nicamente si la clase escuchador es una clase interna. En el caso en que la clase escuchador sea independiente de la clase donde son creados los objetos fuente de evento, hay que revisar el cdigo del mtodo a c t i o n P e r f o r m e d . El parmetro A c t i o n E v e n t del mtodo a c t i o n P e r f o r m e d nos proporciona otra solucin para esquivar este problema. A travs del mtodo g e t A c t i o n C o m m a n dtenemos acceso a una cadena de caracteres que representa el objeto al origen del evento. Por defecto, esta cadena de caracteres corresponde al titulo del componente que activ el evento pero se la puede modificar con el mtodo s e t A c t i o n C o m m a n d de cada componente. De hecho, se recomienda esta prctica ya que nos permite tener un cdigo idntico para una aplicacin que funciona en varios idiomas. A continuacin mostramos las modificaciones correspondientes.
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . C o l o r ; i m p o r tj a v a . a w t . e v e n t . A c t i o n E v e n t ; i m p o r tj a v a . a w t . e v e n t . A c t i o n L i s t e n e r ; i m p o r tj a v a . a w t . e v e n t . W i n d o w A d a p t e r ; i m p o r tj a v a . a w t . e v e n t . W i n d o w E v e n t ; i m p o r tj a v a x . s w i n g . J B u t t o n ; i m p o r tj a v a x . s w i n g . J F r a m e ; i m p o r tj a v a x . s w i n g . J M e n u ; i m p o r tj a v a x . s w i n g . J M e n u B a r ; i m p o r tj a v a x . s w i n g . J M e n u I t e m ; i m p o r tj a v a x . s w i n g . J P a n e l ; p u b l i cc l a s sP a n t a l l ae x t e n d sJ F r a m e { J P a n e lp a n o ; J B u t t o nb t n R o j o , b t n V e r d e , b t n A z u l ; J M e n u I t e mm n u R o j o , m n u V e r d e , m n u A z u l ;
p u b l i cP a n t a l l a( ) { s e t T i t l e ( " p r i m e r av e n t a n ae nJ A V A " ) ; s e t B o u n d s ( 0 , 0 , 3 0 0 , 1 0 0 ) ; s e t D e f a u l t C l o s e O p e r a t i o n ( J F r a m e . D O _ N O T H I N G _ O N _ C L O S E ) ; / /c r e a c i nd el o st r e sb o t o n e s b t n R o j o = n e wJ B u t t o n ( " R o j o " ) ; b t n R o j o . s e t A c t i o n C o m m a n d ( " r e d " ) ; b t n V e r d e = n e wJ B u t t o n ( " V e r d e " ) ; b t n V e r d e . s e t A c t i o n C o m m a n d ( " g r e e n " ) ; b t n A z u l = n e wJ B u t t o n ( " A z u l " ) ; b t n A z u l . s e t A c t i o n C o m m a n d ( " b l u e " ) ; / /c r e a c i nd el o st r e se s c u c h a d o r e s E s c u c h a d o r C o l o re c ; e c = n e wE s c u c h a d o r C o l o r ( ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d ab o t n b t n R o j o . a d d A c t i o n L i s t e n e r ( e c ) ; b t n V e r d e . a d d A c t i o n L i s t e n e r ( e c ) ; b t n A z u l . a d d A c t i o n L i s t e n e r ( e c ) ; / /C r e a c i nd e lm e n J M e n u B a rb a r r a M e n u ; b a r r a M e n u = n e wJ M e n u B a r ( ) ; J M e n um n u C o l o r e s ; m n u C o l o r e s = n e wJ M e n u ( " C o l o r e s " ) ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 19/23
24/4/2014
b a r r a M e n u . a d d ( m n u C o l o r e s ) ; m n u R o j o = n e wJ M e n u I t e m ( " R o j o " ) ; m n u R o j o . s e t A c t i o n C o m m a n d ( " r e d " ) ; m n u V e r d e = n e wJ M e n u I t e m ( " V e r d e " ) ; m n u V e r d e . s e t A c t i o n C o m m a n d ( " g r e e n " ) ; m n u A z u l = n e wJ M e n u I t e m ( " A z u l " ) ; m n u A z u l . s e t A c t i o n C o m m a n d ( " b l u e " ) ; m n u C o l o r e s . a d d ( m n u R o j o ) ; m n u C o l o r e s . a d d ( m n u V e r d e ) ; m n u C o l o r e s . a d d ( m n u A z u l ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d am e n / /(e lm i s m oq u ep a r al o sb o t o n e s) m n u R o j o . a d d A c t i o n L i s t e n e r ( e c ) ; m n u V e r d e . a d d A c t i o n L i s t e n e r ( e c ) ; m n u A z u l . a d d A c t i o n L i s t e n e r ( e c ) ; / /a a d i d od e lm e n e nl av e n t a n a s e t J M e n u B a r ( b a r r a M e n u ) ; / /c r e a c i nd e lc o n t e n e d o ri n t e r m e d i a r i o p a n o = n e wJ P a n e l ( ) ; / /a a d i d od el o sb o t o n e se ne lc o n t e n e d o ri n t e r m e d i a r i o p a n o . a d d ( b t n R o j o ) ; p a n o . a d d ( b t n V e r d e ) ; p a n o . a d d ( b t n A z u l ) ; / /a a d i d od e lc o n t e n e d o ri n t e r m e d i a r i oe ne lC o n t e n t P a n e g e t C o n t e n t P a n e ( ) . a d d ( p a n o ) ; / /c r e a c i nd eu n ai n s t a n c i ad eu n ac l a s ea n n i m a / /e n c a r g a d ad eg e s t i o n a rl o se v e n t o s a d d W i n d o w L i s t e n e r ( n e wW i n d o w A d a p t e r ( ) { p u b l i cv o i dw i n d o w C l o s i n g ( W i n d o w E v e n ta r g 0 ) { S y s t e m . e x i t ( 0 ) ; } } ) ; } p u b l i cc l a s sE s c u c h a d o r C o l o ri m p l e m e n t sA c t i o n L i s t e n e r { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n ta r g 0 ) { S t r i n gc o m a n d o ; c o m a n d o = a r g 0 . g e t A c t i o n C o m m a n d ( ) ; i f( c o m a n d o . e q u a l s ( " r e d " ) ) { p a n o . s e t B a c k g r o u n d ( C o l o r . R E D ) ; } i f( c o m a n d o . e q u a l s ( " g r e e n " ) ) { p a n o . s e t B a c k g r o u n d ( C o l o r . G R E E N ) ; } i f( c o m a n d o . e q u a l s ( " b l u e " ) ) { p a n o . s e t B a c k g r o u n d ( C o l o r . B L U E ) ; } } } } Sealar que en esta solucin, la declaracin de los botones y de los elementos de men pueden ser
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 20/23
24/4/2014
reintegrados en el constructor ya que no les necesitamos ms a nivel de la clase. La ltima etapa de nuestro maratn en los eventos nos va a permitir disponer de varios escuchadores para una misma fuente de eventos y eventualmente suprimir un escuchador existente. Para ello, vamos a crear una nueva clase escuchador que nos va a permitir mostrar en la consola, la fecha y la hora del evento y el objeto al origen del evento.
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . e v e n t . A c t i o n E v e n t ; i m p o r tj a v a . a w t . e v e n t . A c t i o n L i s t e n e r ; i m p o r tj a v a . t e x t . S i m p l e D a t e F o r m a t ; i m p o r tj a v a . u t i l . D a t e ; i m p o r tj a v a x . s w i n g . A b s t r a c t B u t t o n ; i m p o r tj a v a x . s w i n g . J B u t t o n ; i m p o r tj a v a x . s w i n g . J M e n u I t e m ; p u b l i cc l a s sC o n s o l e L o gi m p l e m e n t sA c t i o n L i s t e n e r { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n te ) { S t r i n gm e n s a j e ; S i m p l e D a t e F o r m a ts d f ; s d f = n e wS i m p l e D a t e F o r m a t ( " d d / M M / y y y yh h : m m : s s " ) ; m e n s a j e = s d f . f o r m a t ( n e wF e c h a ( ) ) ; m e n s a j e = m e n s a j e+"c l i ce ne l" ; i f( e . g e t S o u r c e ( )i n s t a n c e o fJ B u t t o n ) { m e n s a j e = m e n s a j e +" b o t n" ; } i f( e . g e t S o u r c e ( )i n s t a n c e o fJ M e n u I t e m ) { m e n s a j e = m e n s a j e +" m e n u" ; } m e n s a j e = m e n s a j e+( ( A b s t r a c t B u t t o n ) e . g e t S o u r c e ( ) ) . g e t T e x t ( ) ; S y s t e m . o u t . p r i n t l n ( m e n s a j e ) ; } } En nuestra aplicacin, aadimos luego una casilla para marcar que nos permite elegir si se visualizan los eventos en la consola. Segn el estado de esta casilla, aadimos con el mtodo a d d A c t i o n L i s t e n e r , o suprimimos con el mtodo r e m o v e A c t i o n L i s t e n e r , un escuchador a los botones y mens. Estos dos mtodos esperan como argumento la instancia del escuchador a aadir o suprimir.
p a c k a g ee s . e n i ; i m p o r tj a v a . a w t . C o l o r ; i m p o r tj a v a . a w t . e v e n t . A c t i o n E v e n t ; i m p o r tj a v a . a w t . e v e n t . A c t i o n L i s t e n e r ; i m p o r tj a v a . a w t . e v e n t . W i n d o w A d a p t e r ; i m p o r tj a v a . a w t . e v e n t . W i n d o w E v e n t ; i m p o r tj a v a x . s w i n g . J B u t t o n ; i m p o r tj a v a x . s w i n g . J C h e c k B o x ; i m p o r tj a v a x . s w i n g . J F r a m e ; i m p o r tj a v a x . s w i n g . J M e n u ; i m p o r tj a v a x . s w i n g . J M e n u B a r ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 21/23
24/4/2014
i m p o r tj a v a x . s w i n g . J M e n u I t e m ; i m p o r tj a v a x . s w i n g . J P a n e l ; p u b l i cc l a s sP a n t a l l ae x t e n d sJ F r a m e { J P a n e lp a n o ; J B u t t o nb t n R o j o , b t n V e r d e , b t n A z u l ; J M e n u I t e mm n u R o j o , m n u V e r d e , m n u A z u l ; C o n s o l e L o gl g ; p u b l i cP a n t a l l a( ) { s e t T i t l e ( " p r i m e r av e n t a n ae nJ A V A " ) ; s e t B o u n d s ( 0 , 0 , 3 0 0 , 1 0 0 ) ; s e t D e f a u l t C l o s e O p e r a t i o n ( J F r a m e . D O _ N O T H I N G _ O N _ C L O S E ) ; / /c r e a c i nd el o st r e sb o t o n e s b t n R o j o = n e wJ B u t t o n ( " R o j o " ) ; b t n R o j o . s e t A c t i o n C o m m a n d ( " r e d " ) ; b t n V e r d e = n e wJ B u t t o n ( " V e r d e " ) ; b t n V e r d e . s e t A c t i o n C o m m a n d ( " g r e e n " ) ; b t n A z u l = n e wJ B u t t o n ( " A z u l " ) ; b t n A z u l . s e t A c t i o n C o m m a n d ( " b l u e " ) ; / /c r e a c i nd el o st r e se s c u c h a d o r e s E s c u c h a d o r C o l o re c ; e c = n e wE s c u c h a d o r C o l o r ( ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d ab o t n b t n R o j o . a d d A c t i o n L i s t e n e r ( e c ) ; b t n V e r d e . a d d A c t i o n L i s t e n e r ( e c ) ; b t n A z u l . a d d A c t i o n L i s t e n e r ( e c ) ; / /c r e a c i nd el ac a s i l l aam a r c a r J C h e c k B o xc h k L o g ; c h k L o g = n e wJ C h e c k B o x ( " l o ge nc o n s o l a " ) ; / /a a d i d od eu ne s c u c h a d o ral ac a s i l l aam a r c a r c h k L o g . a d d A c t i o n L i s t e n e r ( n e wA c t i o n L i s t e n e r ( ) { p u b l i cv o i da c t i o n P e r f o r m e d ( A c t i o n E v e n ta r g 0 ) { J C h e c k B o xc h k ; c h k = ( J C h e c k B o x ) a r g 0 . g e t S o u r c e ( ) ; i f( c h k . i s S e l e c t e d ( ) ) { / /a a d i d od eu ne s c u c h a d o ra d i c i o n a l / /al o sb o t o n e sym e n s l g = n e wC o n s o l e L o g ( ) ; b t n A z u l . a d d A c t i o n L i s t e n e r ( l g ) ; b t n R o j o . a d d A c t i o n L i s t e n e r ( l g ) ; b t n V e r d e . a d d A c t i o n L i s t e n e r ( l g ) ; m n u A z u l . a d d A c t i o n L i s t e n e r ( l g ) ; m n u R o j o . a d d A c t i o n L i s t e n e r ( l g ) ; m n u V e r d e . a d d A c t i o n L i s t e n e r ( l g ) ; } e l s e { / /s u p r e s i nd e le s c u c h a d o ra d i c i o n a l / /d el o sb o t o n e sym e n s b t n A z u l . r e m o v e A c t i o n L i s t e n e r ( l g ) ; b t n R o j o . r e m o v e A c t i o n L i s t e n e r ( l g ) ; b t n V e r d e . r e m o v e A c t i o n L i s t e n e r ( l g ) ; m n u A z u l . r e m o v e A c t i o n L i s t e n e r ( l g ) ; m n u R o j o . r e m o v e A c t i o n L i s t e n e r ( l g ) ;
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887 22/23
24/4/2014
m n u V e r d e . r e m o v e A c t i o n L i s t e n e r ( l g ) ; } } } ) ; / /C r e a c i nd e lm e n J M e n u B a rb a r r a M e n u ; b a r r a M e n u = n e wJ M e n u B a r ( ) ; J M e n um n u C o l o r e s ; m n u C o l o r e s = n e wJ M e n u ( " C o l o r e s " ) ; b a r r a M e n u . a d d ( m n u C o l o r e s ) ; m n u R o j o = n e wJ M e n u I t e m ( " R o j o " ) ; m n u R o j o . s e t A c t i o n C o m m a n d ( " r e d " ) ; m n u V e r d e = n e wJ M e n u I t e m ( " V e r d e " ) ; m n u V e r d e . s e t A c t i o n C o m m a n d ( " g r e e n " ) ; m n u A z u l = n e wJ M e n u I t e m ( " A z u l " ) ; m n u A z u l . s e t A c t i o n C o m m a n d ( " b l u e " ) ; m n u C o l o r e s . a d d ( m n u R o j o ) ; m n u C o l o r e s . a d d ( m n u V e r d e ) ; m n u C o l o r e s . a d d ( m n u A z u l ) ; / /a s o c i a c i nd e le s c u c h a d o rac a d am e n / /(e l m i s m oq u ep a r al o sb o t o n e s) m n u R o j o . a d d A c t i o n L i s t e n e r ( e c ) ; m n u V e r d e . a d d A c t i o n L i s t e n e r ( e c ) ; m n u A z u l . a d d A c t i o n L i s t e n e r ( e c ) ; / /a a d i d od e lm e n e nl av e n t a n a s e t J M e n u B a r ( b a r r a M e n u ) ; / /c r e a c i nd e lc o n t e n e d o ri n t e r m e d i a r i o
http://www.eni-training.com/client_net/mediabook.aspx?idR=65887
23/23