Sei sulla pagina 1di 101

Unidad10.

Polimorfismo
10.1Introduccin
El polimorfismo nos permite escribir programas para procesar objetos que compartan la misma superclase en una jerarquadeclases,comositodosfueranobjetosdelasuperclase;estopuedesimplificarlaprogramacin. Con el polimorfismo, podemos disear e implementar sistemas que puedan extenderse con facilidad; pueden agregarse nuevas clases con slo modificar un poco (o nada) las porciones generales del programa, siempre y cuando las nuevas clases sean parte de la jerarqua de herencia que el programa procesa en forma genrica. Las nicas partes de un programa que deben alterarse para dar cabida a las nuevas clases son las que requieren un conocimientodirectodelasnuevasclasesqueelprogramadoragregaralajerarqua.

10.3Demostracindelcomportamientopolimrfico
Cuando el compilador encuentra una llamada a un mtodo que se realiza a travs de una variable, determina si el mtodo puede llamarse verificando el tipo de clase de la variable. Si esa clase contiene la declaracin del mtodo apropiada (o hereda una), se compila la llamada. En tiempo de ejecucin, el tipo del objeto al cual se refiere la variableeselquedeterminaelmtodoqueseutilizar.

//Fig.10.1:PruebaPolimorfismo.java //Asignacindereferenciasalasuperclaseylasubclase,avariablesdelasuperclaseylasubclase. publicclassPruebaPolimorfismo{ publicstaticvoidmain(Stringargs[]){ //asignalareferenciaalasuperclaseaunavariabledelasuperclase EmpleadoPorComision3empleadoPorComision=newEmpleadoPorComision3( "Sue","Jones","222222222",10000,.06); //asignalarefernciaalasubclaseaunavariabledelasubclase EmpleadoBaseMasComision4empleadoBaseMasComision= newEmpleadoBaseMasComision4( "Bob","Lewis","333333333",5000,.04,300); //invocaatoStringenunobjetodelasuperclase,usandounavariabledelasuperclase System.out.printf("%s%s:\n\n%s\n\n", "LlamadaatoStringdeEmpleadoPorComision3conreferenciadesuperclase", "aunobjetodelasuperclase",empleadoPorComision.toString()); //invocaatoStringenunobjetodelasubclase,usandounavariabledelasubclase System.out.printf("%s%s:\n\n%s\n\n", "LlamadaatoStringdeEmpleadoBaseMasComision4conreferencia", "desubclaseaunobjetodelasubclase", empleadoBaseMasComision.toString()); //invocaatoStringenunobjetodelasubclase,usandounavariabledelasuperclase EmpleadoPorComision3empleadoPorComision2= empleadoBaseMasComision; System.out.printf("%s%s:\n\n%s\n", "LlamadaatoStringdeEmpleadoBaseMasComision4conreferenciadesuperclase", "aunobjetodelasubclase",empleadoPorComision2.toString()); }//findemain }//findelaclasePruebaPolimorfismo

Llamada a toString de EmpleadoPorComision3 con referencia de superclase a un objeto de la superclase: empleado por comision: Sue Jones numero de seguro social: 222-22-2222 ventas brutas: 10000.00 tarifa de comision: 0.06 Llamada a toString de EmpleadoBaseMasComision4 con referencia de subclase a un objeto de la subclase: sueldo base empleado por comision: Bob Lewis con numero de seguro social: 333-33-3333 ventas brutas: 5000.00 tarifa de comision: 0.04 sueldo base: 300.00 Llamada a toString de EmpleadoBaseMasComision4 con referencia de superclase a un objeto de la subclase: con sueldo base empleado por comision: Bob Lewis numero de seguro social: 333-33-3333 ventas brutas: 5000.00 tarifa de comision: 0.04 sueldo base: 300.00 10.4Clasesymtodosabstractos

Enalgunoscasosesconvenientedeclararclasesparalascualesnotenemoslaintencindecrearinstanciasdeobjetos. A dichas clases se les conoce como clases abstractas. Como se utilizan slo como superclases en jerarquas de herencia, nos referimos a ellas como superclases abstractas. Estas clases no pueden utilizarse para instanciar objetos, ya que estn incompletas. Elpropsitoprincipaldeunaclaseabstractaesproporcionarunasuperclaseapropiada,apartirdelacualpuedanheredar otrasclasesy,porende,compartirundiseocomn. Las clases que pueden utilizarse para instanciar objetos se llaman clases concretas. Dichas clases proporcionan implementacionesdecadamtodoquedeclaran(algunasdelasimplementacionespuedenheredarse). No todas las jerarquas de herencia contienen clases abstractas. Sin embargo, a menudo los programadores escriben cdigoclientequeutilizaslotiposdesuperclasesabstractasparareducirlasdependenciasdelcdigoclienteenunrango detiposdesubclasesespecficas. Algunasveceslasclasesabstractasconstituyenvariosnivelesdelajerarqua. Para hacer una clase abstracta, sta se declara con la palabra clave abstract. Por lo general, una clase abstracta contiene unoomsmtodosabstractos. Losmtodosabstractosnoproporcionanimplementaciones. Una clase que contiene mtodos abstractos debe declararse como clase abstracta, aun si esa clase contiene mtodos concretos (no abstractos). Cada subclase concreta de una superclase abstracta tambin debe proporcionar implementacionesconcretasdelosmtodosabstractosdelasuperclase. Losconstructoresylosmtodosstaticnopuedendeclararsecomoabstract. Aunque no podemos instanciar objetos de superclases abstractas, s podemos usar superclases abstractas para declarar variables que puedan guardar referencias a objetos de cualquier clase concreta que se derive de esas superclases abstractas. Por lo general, los programas utilizan dichas variables para manipular los objetos de las subclases mediante el polimorfismo. Enespecial,elpolimorfismoesefectivoparaimplementarlossistemasdesoftwareencapas.

10.5Ejemploprctico:sistemadenminautilizandopolimorfismo
Al incluir un mtodo abstracto en una superclase, obligamos a cada subclase directa de la superclase a sobrescribir ese mtodo abstracto para que pueda convertirse en una clase concreta. Esto permite al diseador de la jerarqua de clases demandarquecadasubclaseconcretaproporcioneunaimplementacinapropiadadelmtodo. La mayora de las llamadas a los mtodos se resuelven en tiempo de ejecucin, con base en el tipo del objeto que se est manipulando.Esteprocesoseconocecomovinculacindinmicaovinculacinpostergada. Unareferenciaalasuperclasepuedeutilizarseparainvocarsloamtodosdelasuperclase(ylasuperclasepuedeinvocar versionessobrescritasdestosenlasubclase).

El operador instanceof se puede utilizar para determinar si el tipo de un objeto especfico tiene la relacin es un conuntipoespecfico. TodoslosobjetosenJavaconocensupropiaclaseypuedenaccederaestainformacinatravsdelmtodo

getClass, que todas las clases heredan de la clase Object. El mtodo getClass devuelve un objeto de tipo Class (del paquetejava.lang),elcualcontieneinformacinacercadeltipodelobjeto,incluyendoelnombredesuclase. Larelacinesunseaplicasloentrelasubclaseysussuperclases,noviceversa. Noestpermitidotratardeinvocaralosmtodosqueslopertenecenalasubclase,enunareferenciaalasuperclase. Aunque el mtodo que se llame en realidad depende del tipo del objeto en tiempo de ejecucin, podemos usar una variableparainvocarsloalosmtodosqueseanmiembrosdeltipodeesavariable,queelcompiladorverifica.

//Fig.10.4:Empleado.javaLasuperclaseabstractaEmpleado.

publicabstractclassEmpleado{ privateStringprimerNombre; privateStringapellidoPaterno; privateStringnumeroSeguroSocial;

//constructorcontresargumentos publicEmpleado(Stringnombre,Stringapellido,Stringnss){ primerNombre=nombre; apellidoPaterno=apellido; numeroSeguroSocial=nss; }//findelconstructordeEmpleadocontresargumentos

//estableceelprimernombre publicvoidestablecerPrimerNombre(Stringnombre){ primerNombre=nombre; }//findelmtodoestablecerPrimerNombre

//devuelveelprimernombre publicStringobtenerPrimerNombre(){ returnprimerNombre; }//findelmtodoobtenerPrimerNombre

//estableceelapellidopaterno publicvoidestablecerApellidoPaterno(Stringapellido){ apellidoPaterno=apellido; }//findelmtodoestablecerApellidoPaterno

//devuelveelapellidopaterno publicStringobtenerApellidoPaterno(){ returnapellidoPaterno; }//findelmtodoobtenerApellidoPaterno

//estableceelnmerodesegurosocial publicvoidestablecerNumeroSeguroSocial(Stringnss){ numeroSeguroSocial=nss;//debevalidar }//findelmtodoestablecerNumeroSeguroSocial

//devuelveelnmerodesegurosocial publicStringobtenerNumeroSeguroSocial(){ returnnumeroSeguroSocial; }//findelmtodoobtenerNumeroSeguroSocial

//devuelverepresentacinStringdeunobjetoEmpleado publicStringtoString(){ returnString.format("%s%s\nnumerodesegurosocial:%s", obtenerPrimerNombre(),obtenerApellidoPaterno(),obtenerNumeroSeguroSocial()); }//findelmtodotoString

//mtodoabstractosobrescritoporlassubclases publicabstractdoubleingresos();//aqunohayimplementacin

}//findelaclaseabstractaEmpleado

//Fig.10.5:EmpleadoAsalariado.javaLaclaseEmpleadoAsalariadoextiendeaEmpleado.

publicclassEmpleadoAsalariadoextendsEmpleado{ privatedoublesalarioSemanal;

//constructordecuatroargumentos publicEmpleadoAsalariado(Stringnombre,Stringapellido,Stringnss,doublesalario){ super(nombre,apellido,nss);//lospasaalconstructordeEmpleado establecerSalarioSemanal(salario);//validayalmacenaelsalario }//findelconstructordeEmpleadoAsalariadoconcuatroargumentos

//estableceelsalario publicvoidestablecerSalarioSemanal(doublesalario){ salarioSemanal=salario<0.0?0.0:salario; }//findelmtodoestablecerSalarioSemanal

//devuelveelsalario publicdoubleobtenerSalarioSemanal(){ returnsalarioSemanal; }//findelmtodoobtenerSalarioSemanal //calculalosingresos;sobrescribeelmtodoabstractoingresosenEmpleado publicdoubleingresos(){ returnobtenerSalarioSemanal(); }//findelmtodoingresos

//devuelverepresentacinStringdeunobjetoEmpleadoAsalariado publicStringtoString(){ returnString.format("empleadoasalariado:%s\n%s:$%,.2f", super.toString(),"salariosemanal",obtenerSalarioSemanal());

}//findelmtodotoString }//findelaclaseEmpleadoAsalariado

//Fig.10.6:EmpleadoPorHoras.javaLaclaseEmpleadoPorHorasextiendeaEmpleado. publicclassEmpleadoPorHorasextendsEmpleado{ privatedoublesueldo;//sueldoporhora privatedoublehoras;//horastrabajadasporsemana //constructorconcincoargumentos publicEmpleadoPorHoras(Stringnombre,Stringapellido,Stringnss, doublesueldoPorHoras,doublehorasTrabajadas){ super(nombre,apellido,nss); establecerSueldo(sueldoPorHoras);//validayalmacenaelsueldoporhoras establecerHoras(horasTrabajadas);//validayalmacenalashorastrabajadas }//findelconstructordeEmpleadoPorHorasconcincoargumentos //estableceelsueldo publicvoidestablecerSueldo(doublesueldoPorHoras){ sueldo=(sueldoPorHoras<0.0)?0.0:sueldoPorHoras; }//findelmtodoestablecerSueldo //devuelveelsueldo publicdoubleobtenerSueldo(){ returnsueldo; }//findelmtodoobtenerSueldo //establecelashorastrabajadas publicvoidestablecerHoras(doublehorasTrabajadas){ horas=((horasTrabajadas>=0.0)&&(horasTrabajadas<=168.0))? horasTrabajadas:0.0; }//findelmtodoestablecerHoras Figura 10.6 | La clase EmpleadoPorHoras derivada de Empleado (Parte 1 de 2).

Figura 10.6 | La clase EmpleadoPorHoras derivada de Empleado (Parte 2 de 2). //Fig.10.7:EmpleadoPorComision.javaLaclaseEmpleadoPorComisionextiendeaEmpleado. publicclassEmpleadoPorComisionextendsEmpleado{ privatedoubleventasBrutas;//ventastotalesporsemana privatedoubletarifaComision;//porcentajedecomisin //constructorconcincoargumentos publicEmpleadoPorComision(Stringnombre,Stringapellido,Stringnss,doubleventas,doubletarifa){ super(nombre,apellido,nss); establecerVentasBrutas(ventas); establecerTarifaComision(tarifa); }//findelconstructordeEmpleadoPorComisionconcincoargumentos //establecelatarifadecomisin publicvoidestablecerTarifaComision(doubletarifa){ tarifaComision=(tarifa>0.0&&tarifa<1.0)?tarifa:0.0; }//findelmtodoestablecerTarifaComision //devuelvelatarifadecomisin publicdoubleobtenerTarifaComision(){ returntarifaComision; }//findelmtodoobtenerTarifaComision //estableceelmontodeventasbrutas publicvoidestablecerVentasBrutas(doubleventas){ ventasBrutas=(ventas<0.0)?0.0:ventas; }//findelmtodoestablecerVentasBrutas //devuelveelmontodeventasbrutas publicdoubleobtenerVentasBrutas(){ returnventasBrutas; }//findelmtodoobtenerVentasBrutas Figura 10.7 | La clase EmpleadoPorComision derivada de Empleado. (Parte 1 de 2).

//devuelvelashorastrabajadas publicdoubleobtenerHoras(){ returnhoras; }//findelmtodoobtenerHoras //calculalosingresos;sobrescribeelmtodoabstractoingresosenEmpleado publicdoubleingresos(){ if(obtenerHoras()<=40)//nohaytiempoextra returnobtenerSueldo()*obtenerHoras(); else return40*obtenerSueldo()+(obtenerHoras()40)*obtenerSueldo()*1.5; }//findelmtodoingresos //devuelverepresentacinStringdeunobjetoEmpleadoPorHoras publicStringtoString(){ returnString.format("empleadoporhoras:%s\n%s:$%,.2f;%s:%,.2f", super.toString(),"sueldoporhora",obtenerSueldo(), "horastrabajadas",obtenerHoras()); }//findelmtodotoString }//findelaclaseEmpleadoPorHoras

//calculalosingresos;sobrescribeelmtodoabstractoingresosenEmpleado publicdoubleingresos(){ returnobtenerTarifaComision()*obtenerVentasBrutas(); }//findelmtodoingresos //devuelverepresentacinStringdeunobjetoEmpleadoPorComision publicStringtoString(){ returnString.format("%s:%s\n%s:$%,.2f;%s:%.2f", "empleadoporcomision",super.toString(), "ventasbrutas",obtenerVentasBrutas(), "tarifadecomision",obtenerTarifaComision()); }//findelmtodotoString }//findelaclaseEmpleadoPorComision

Figura 10.7 | La clase EmpleadoPorComision derivada de Empleado. (Parte 2 de 2). //Fig.10.8:EmpleadoBaseMasComision.java //LaclaseEmpleadoBaseMasComisionextiendeaEmpleadoPorComision. publicclassEmpleadoBaseMasComisionextendsEmpleadoPorComision{ privatedoublesalarioBase;//salariobaseporsemana //constructorconseisargumentos publicEmpleadoBaseMasComision(Stringnombre,Stringapellido, Stringnss,doubleventas,doubletarifa,doublesalario){ super(nombre,apellido,nss,ventas,tarifa); establecerSalarioBase(salario);//validayalmacenaelsalariobase }//findelconstructordeEmpleadoBaseMasComisionconseisargumentos //estableceelsalariobase publicvoidestablecerSalarioBase(doublesalario){ salarioBase=(salario<0.0)?0.0:salario;//positivo }//findelmtodoestablecerSalarioBase //devuelveelsalariobase publicdoubleobtenerSalarioBase(){ returnsalarioBase; }//findelmtodoobtenerSalarioBase //calculalosingresos;sobrescribeelmtodoingresosenEmpleadoPorComision publicdoubleingresos(){ returnobtenerSalarioBase()+super.ingresos(); }//findelmtodoingresos //devuelverepresentacinStringdeunobjetoEmpleadoBaseMasComision publicStringtoString(){ returnString.format("%s%s;%s:$%,.2f", "consalariobase",super.toString(), "salariobase",obtenerSalarioBase()); }//findelmtodotoString }//findelaclaseEmpleadoBaseMasComision

//Fig.10.9:PruebaSistemaNomina.java //ProgramadepruebaparalajerarquadeEmpleado. publicclassPruebaSistemaNomina{ publicstaticvoidmain(Stringargs[]){ //creaobjetosdelassubclases EmpleadoAsalariadoempleadoAsalariado=newEmpleadoAsalariado("John","Smith","111111111",800.00); EmpleadoPorHorasempleadoPorHoras=newEmpleadoPorHoras("Karen","Price","222222222",16.75,40); EmpleadoPorComisionempleadoPorComision=newEmpleadoPorComision("Sue","Jones","333333333",10000,.06); EmpleadoBaseMasComisionempleadoBaseMasComision=newEmpleadoBaseMasComision( "Bob","Lewis","444444444",5000,.04,300); System.out.println("Empleadosprocesadosporseparado:\n"); System.out.printf("%s\n%s:$%,.2f\n\n",empleadoAsalariado,"ingresos",empleadoAsalariado.ingresos()); System.out.printf("%s\n%s:$%,.2f\n\n",empleadoPorHoras,"ingresos",empleadoPorHoras.ingresos()); System.out.printf("%s\n%s:$%,.2f\n\n",empleadoPorComision,"ingresos",empleadoPorComision.ingresos()); System.out.printf("%s\n%s:$%,.2f\n\n",empleadoBaseMasComision,"ingresos", empleadoBaseMasComision.ingresos()); //creaunarregloEmpleadodecuatroelementos Empleadoempleados[]=newEmpleado[4]; //inicializaelarregloconobjetosEmpleado empleados[0]=empleadoAsalariado; empleados[1]=empleadoPorHoras; empleados[2]=empleadoPorComision; empleados[3]=empleadoBaseMasComision; System.out.println("Empleadosprocesadosenformapolimorfica:\n"); //procesaenformagenricaacadaelementoenelarreglodeempleados for(EmpleadoempleadoActual:empleados){ System.out.println(empleadoActual);//invocaatoString //determinasielelementoesunEmpleadoBaseMasComision if(empleadoActualinstanceofEmpleadoBaseMasComision){ //conversindescendentedelareferenciadeEmpleadoaunareferenciadeEmpleadoBaseMasComision EmpleadoBaseMasComisionempleado=(EmpleadoBaseMasComision)empleadoActual; doublesalarioBaseAnterior=empleado.obtenerSalarioBase(); empleado.establecerSalarioBase(1.10*salarioBaseAnterior); System.out.printf( "elnuevosalariobasecon10%%deaumentoes:$%,.2f\n",empleado.obtenerSalarioBase()); }//findeif System.out.printf("ingresos$%,.2f\n\n",empleadoActual.ingresos()); }//findefor //obtieneelnombredeltipodecadaobjetoenelarreglodeempleados for(intj=0;j<empleados.length;j++) System.out.printf("Elempleado%desun%s\n",j, empleados[j].getClass().getName());

}//findemain }//findelaclasePruebaSistemaNomina

Empleados procesados por separado: empleado asalariado: John Smith numero de seguro social: 111-11-1111 salario semanal: $800.00 ingresos: $800.00 empleado por horas: Karen Price numero de seguro social: 222-22-2222 sueldo por hora: $16.75; horas trabajadas: 40.00 ingresos: $670.00 empleado por comision: Sue Jones numero de seguro social: 333-33-3333 ventas brutas: $10,000.00; tarifa de comision: 0.06 ingresos: $600.00 con salario base empleado por comision: Bob Lewis numero de seguro social: 444-44-4444 ventas brutas: $5,000.00; tarifa de comision: 0.04; salario base: $300.00 ingresos: $500.00 Empleados procesados en forma polimorfica: empleado asalariado: John Smith numero de seguro social: 111-11-1111 salario semanal: $800.00 ingresos $800.00 empleado por horas: Karen Price numero de seguro social: 222-22-2222 sueldo por hora: $16.75; horas trabajadas: 40.00 ingresos $670.00 empleado por comision: Sue Jones numero de seguro social: 333-33-3333 ventas brutas: $10,000.00; tarifa de comision: 0.06 ingresos $600.00 con salario base empleado por comision: Bob Lewis numero de seguro social: 444-44-4444 ventas brutas: $5,000.00; tarifa de comision: 0.04; salario base: $300.00 el nuevo salario base con 10% de aumento es : $330.00 ingresos $530.00 El empleado 0 es un EmpleadoAsalariado El empleado 1 es un EmpleadoPorHoras El empleado 2 es un EmpleadoPorComision El empleado 3 es un EmpleadoBaseMasComision

10.6Mtodosyclasesfinal
Unmtodoquesedeclaracomofinalenunasuperclasenosepuederedefinirenunasubclase. Los mtodos que se declaran como private son final de manera implcita, ya que es imposible sobrescribirlos en una subclase. Losmtodosquesedeclarancomostaticsonfinaldemaneraimplcita. La declaracin de un mtodo final no puede cambiar, por lo que todas las subclases utilizan la misma implementacin del mtodo, y las llamadas a los mtodos final se resuelven en tiempo de compilacin; a esto se le conoce como vinculacin esttica. Como el compilador sabe que los mtodos final no se pueden sobrescribir, puede optimizar los programas al eliminar las llamadasalosmtodosfinalysustituirlasconelcdigoexpandidodesusdeclaracionesencadaunadelasubicacionesde lasllamadasalmtodo;aestatcnicaseleconocecomoponerelcdigoenlnea. Unaclasequesedeclaracomofinalnopuedeserunasuperclase(esdecir,unaclasenopuedeextenderaunaclasefinal). Todoslosmtodosenunaclasefinalsonimplcitamentefinal.

10.7Ejemploprctico:creacinyusodeinterfaces
Las interfaces definen y estandarizan las formas en que las cosas como las personas y los sistemas pueden interactuarentres. Unainterfazespecificaquoperacionesestnpermitidas,peronoespecificacmoserealizanestasoperaciones. UnainterfazdeJavadescribeaunconjuntodemtodosquepuedenllamarseenunobjeto. Ladeclaracindeunainterfazempiezaconlapalabraclaveinterfaceyslocontieneconstantesymtodosabstract. Todos los miembros de una interfaz deben ser public, y las interfaces no pueden especificar ningn detalle de implementacin,comolasdeclaracionesdemtodosconcretosylasvariablesdeinstancia. Todoslosmtodosquesedeclaranenunainterfazsonpublicabstractdemaneraimplcita,ytodosloscamposson public,staticyfinaldemaneraimplcita. Para utilizar una interfaz, una clase concreta debe especificar que implementa (implements) a esa interfaz, y debe declarar cada uno de los mtodos de la interfaz con la firma especificada en su declaracin. Una clase que no implementaatodoslosmtodosdeunainterfazesunaclaseabstracta,porlocualdebedeclararsecomoabstract. Implementar una interfaz es como firmar un contrato con el compilador que diga, Declarar todos los mtodos especificadosporlainterfaz,odeclararmiclasecomoabstract. Porlogeneral,unainterfazseutilizacuandoclasesdispares(esdecir,norelacionadas)necesitancompartirmtodos yconstantescomunes.Estopermitequelosobjetosdeclasesnorelacionadasseprocesenenformapolimrfica;los objetosdeclasesqueimplementanlamismainterfazpuedenresponderalasmismasllamadasamtodos. Usted puede crear una interfaz que describa la funcionalidad deseada, y despus implementar esa interfaz en cualquierclasequerequieraesafuncionalidad. A menudo, una interfaz se utiliza en vez de una clase abstract cuando no hay una implementacin predeterminada queheredar;estoes,nohaycamposniimplementacionesdemtodospredeterminadas. Al igual que las clases public abstract, las interfaces son comnmente de tipo public, por lo que se declaran en archivosporssolasconelmismonombrequelainterfaz,ylaextensindearchivo.java. Java no permite que las subclases hereden de ms de una superclase, pero s permite que una clase herede de una superclase e implemente ms de una interfaz. Para implementar ms de una interfaz, utilice una lista separada por comasdenombresdeinterfazdespusdelapalabraclaveimplementsenladeclaracindelaclase. Todos los objetos de una clase que implementan varias interfaces tienen la relacin es un con cada tipo de interfazimplementada. Unainterfazpuededeclararconstantes.Lasconstantessonimplcitamentepublic,staticyfinal.

//Fig.10.11:PorPagar.javaDeclaracindelainterfazPorPagar.

publicinterfacePorPagar{ doubleobtenerMontoPago();//calculaelpago;nohayimplementacin }//findelainterfazPorPagar

//Fig.10.12:Factura.javaLaclaseFacturaimplementaaPorPagar.

publicclassFacturaimplementsPorPagar{ privateStringnumeroPieza; privateStringdescripcionPieza; privateintcantidad; privatedoubleprecioPorArticulo;

//constructorconcuatroargumentos publicFactura(Stringpieza,Stringdescripcion,intcuenta,doubleprecio){ numeroPieza=pieza; descripcionPieza=descripcion; establecerCantidad(cuenta);//validayalmacenalacantidad establecerPrecioPorArticulo(precio);//validayalmacenaelprecioporartculo }//findelconstructordeFacturaconcuatroargumentos publicvoidestablecerNumeroPieza(Stringpieza){//estableceelnmerodepieza numeroPieza=pieza; }//findelmtodoestablecerNumeroPieza publicStringobtenerNumeroPieza(){//obtenernmerodepieza returnnumeroPieza; }//findelmtodoobtenerNumeroPieza publicvoidestablecerDescripcionPieza(Stringdescripcion){//estableceladescripcin descripcionPieza=descripcion; }//findelmtodoestablecerDescripcionPieza publicStringobtenerDescripcionPieza(){//obtieneladescripcin returndescripcionPieza; }//findelmtodoobtenerDescripcionPieza publicvoidestablecerCantidad(intcuenta){//establecelacantidad cantidad=(cuenta<0)?0:cuenta;//cantidadnopuedesernegativa }//findelmtodoestablecerCantidad

publicintobtenerCantidad(){//obtenercantidad returncantidad; }//findelmtodoobtenerCantidad

//estableceelprecioporartculo publicvoidestablecerPrecioPorArticulo(doubleprecio){ precioPorArticulo=(precio<0.0)?0.0:precio;//validaelprecio }//findelmtodoestablecerPrecioPorArticulo

publicdoubleobtenerPrecioPorArticulo(){//obtieneelprecioporartculo returnprecioPorArticulo; }//findelmtodoobtenerPrecioPorArticulo

publicStringtoString(){//devuelverepresentacinStringdeunobjetoFactura returnString.format("%s:\n%s:%s(%s)\n%s:%d\n%s:$%,.2f", "factura","numerodepieza",obtenerNumeroPieza(),obtenerDescripcionPieza(), "cantidad",obtenerCantidad(),"precioporarticulo",obtenerPrecioPorArticulo()); }//findelmtodotoString

//mtodorequeridopararealizarelcontratoconlainterfazPorPagar publicdoubleobtenerMontoPago(){ returnobtenerCantidad()*obtenerPrecioPorArticulo();//calculaelcostototal

}//findelmtodoobtenerMontoPago }//findelaclaseFactura

//Fig.10.13:Empleado.java //LasuperclasesabstractaEmpleadoimplementaaPorPagar. publicabstractclassEmpleadoimplementsPorPagar{ privateStringprimerNombre; privateStringapellidoPaterno; privateStringnumeroSeguroSocial; //constructorcontresargumentos publicEmpleado(Stringnombre,Stringapellido,Stringnss){ primerNombre=nombre; apellidoPaterno=apellido; numeroSeguroSocial=nss; }//findelconstructordeEmpleadocontresargumentos //estableceelprimernombre publicvoidestablecerPrimerNombre(Stringnombre){ primerNombre=nombre; }//findelmtodoestablecerPrimerNombre //devuelveelprimernombre publicStringobtenerPrimerNombre(){ returnprimerNombre; }//findelmtodoobtenerPrimerNombre //estableceelapellidopaterno publicvoidestablecerApellidoPaterno(Stringapellido){ apellidoPaterno=apellido; }//findelmtodoestablecerApellidoPaterno //devuelveelapellidopaterno publicStringobtenerApellidoPaterno(){ returnapellidoPaterno; }//findelmtodoobtenerApellidoPaterno //estableceelnmerodesegurosocial publicvoidestablecerNumeroSeguroSocial(Stringnss){ numeroSeguroSocial=nss;//debevalidar }//findelmtodoestablecerNumeroSeguroSocial //devuelveelnmerodesegurosocial publicStringobtenerNumeroSeguroSocial(){ returnnumeroSeguroSocial; }//findelmtodoobtenerNumeroSeguroSocial //devuelverepresentacinStringdeunobjetoEmpleado publicStringtoString(){ returnString.format("%s%s\nnumerodesegurosocial:%s", obtenerPrimerNombre(),obtenerApellidoPaterno(),obtenerNumeroSeguroSocial()); }//findelmtodotoString //Nota:AqunoimplementamoselmtodoobtenerMontoPagodePorPagar,asque //estaclasedebedeclararsecomoabstractparaevitarunerrordecompilacin. }//findelaclaseabstractaEmpleado

//Fig.10.14:EmpleadoAsalariado.java //LaclaseEmpleadoAsalariadoextiendeaEmpleado,queimplementaaPorPagar.

publicclassEmpleadoAsalariadoextendsEmpleado{ privatedoublesalarioSemanal;

//constructorconcuatroargumentos publicEmpleadoAsalariado(Stringnombre,Stringapellido,Stringnss,doublesalario){ super(nombre,apellido,nss);//pasaargumentosalconstructordeEmpleado establecerSalarioSemanal(salario);//validayalmacenaelsalario }//findelconstructordeEmpleadoAsalariadoconcuatroargumentos

//estableceelsalario publicvoidestablecerSalarioSemanal(doublesalario){ salarioSemanal=salario<0.0?0.0:salario; }//findelmtodoestablecerSalarioSemanal

//devuelveelsalario publicdoubleobtenerSalarioSemanal(){ returnsalarioSemanal; }//findelmtodoobtenerSalarioSemanal

//calculalosingresos;implementaelmtododelainterfazPorPagar //queeraabstractoenlasuperclaseEmpleado publicdoubleobtenerMontoPago(){ returnobtenerSalarioSemanal(); }//findelmtodoobtenerMontoPago

//devuelverepresentacinStringdeunobjetoEmpleadoAsalariado publicStringtoString(){ returnString.format("empleadoasalariado:%s\n%s:$%,.2f", super.toString(),"salariosemanal",obtenerSalarioSemanal()); }//findelmtodotoString }//findelaclaseEmpleadoAsalariado

//Fig.10.15:PruebaInterfazPorPagar.javaPruebalainterfazPorPagar.

publicclassPruebaInterfazPorPagar{ publicstaticvoidmain(Stringargs[]){ //creaarregloPorPagarconcuatroelementos PorPagarobjetosPorPagar[]=newPorPagar[4]; //llenaelarregloconobjetosqueimplementanlainterfazPorPagar objetosPorPagar[0]=newFactura("01234","asiento",2,375.00); objetosPorPagar[1]=newFactura("56789","llanta",4,79.95); objetosPorPagar[2]=newEmpleadoAsalariado("John","Smith","111111111",800.00); objetosPorPagar[3]=newEmpleadoAsalariado("Lisa","Barnes","888888888",1200.00);

System.out.println("FacturasyEmpleadosprocesadosenformapolimorfica:\n");

//procesaenformagenricacadaelementoenelarregloobjetosPorPagar for(PorPagarporPagarActual:objetosPorPagar){ //imprimeporPagarActualysumontodepagoapropiado System.out.printf("%s\n%s:$%,.2f\n\n",porPagarActual.toString(),"pagovencido", porPagarActual.obtenerMontoPago()); }//findefor }//findemain }//findelaclasePruebaInterfazPorPagar

10.7.8InterfacescomunesdelaAPIdeJava

Unidad11.ComponentesdelaGUI:ParteUno

11.1Introduccin
Una interfaz grfica de usuario (GUI) presenta un mecanismo amigable al usuario para interactuar con una aplicacin.UnaGUIproporcionaaunaaplicacinunaaparienciavisualnica. Al proporcionar distintas aplicaciones en las que los componentes de la interfaz de usuario sean consistentes e intuitivos, losusuarios pueden familiarizarse en cierto modo conunaaplicacin,demanera que pueden aprender a utilizarlaenmenortiempoyconmayorproductividad. LasGUIssecreanapartirdecomponentesdeGUI;astosselesconocealgunasvecescomocontrolesowidgets.

11.2Entrada/salidasimplebasadaenGUIconJOptionPane
La mayora de las aplicaciones utilizan ventanas o cuadros de dilogo (tambin conocidos como dilogos) para interactuarconelusuario. La clase JOptionPane de Java (paquete javax.swing) proporciona cuadros de dilogo preempaquetados para entradaysalida.ElmtodostaticshowInputDialogdeJOptionPanemuestraundilogodeentrada. Por lo general, un indicador utiliza la capitalizacin estilo oracin: un estilo que capitaliza slo la primera letra de la primerapalabraeneltexto,amenosquelapalabraseaunnombrepropio. Un dilogo de entrada slo puede introducir objetos String. Esto es comn en la mayora de los componentes de la GUI. ElmtodostaticshowMessageDialogdeJOptionPanemuestraundilogodemensaje.
//Fig.11.2:Suma.javaProgramadesumaqueutilizaaJOptionPaneparaentradaysalida. importjavax.swing.JOptionPane;//elprogramausaJOptionPane

publicclassSuma{ publicstaticvoidmain(Stringargs[]){ //obtienelaentradadelusuariodelosdilogosdeentradadeJOptionPane StringprimerNumero=JOptionPane.showInputDialog("Introduzcaelprimerentero"); StringsegundoNumero=JOptionPane.showInputDialog("Introduzcaelsegundoentero");

//conviertelasentradasStringenvaloresintparausarlosenunclculo intnumero1=Integer.parseInt(primerNumero); intnumero2=Integer.parseInt(segundoNumero);

intsuma=numero1+numero2;//sumanmeros

//muestralosresultadosenundilogodemensajesdeJOptionPane JOptionPane.showMessageDialog(null,"Lasumaes"+suma,"Sumadedosenteros",JOptionPane.PLAIN_MESSAGE); }//findelmtodomain }//findelaclaseSuma

Figura 11.3 | Constantes static de JOptionPane para dilogos de mensaje.

11.3GeneralidadesdeloscomponentesdeSwing
La mayora de los componentes de GUI de Swing se encuentran en el paquete javax.swing. Forman parte de las Java FoundationClasses(JFC):lasbibliotecasdeJavaparaeldesarrollodeGUIsendistintasplataformas. En conjunto, a la apariencia y la forma en la que interacta el usuario con la aplicacin se les denomina la apariencia visual. Los componentes de GUI de Swing nos permiten especificar una apariencia visual uniforme para una aplicacin a travsdetodaslasplataformas,oparausarlaaparienciavisualpersonalizadadecadaplataforma. Los componentes ligeros de Swing no estn enlazados a los componentes actuales de GUI que soporte la plataforma subyacenteenlaqueseejecutaunaaplicacin. Varios componentes de Swing son componentes pesados, que requieren una interaccin directa con el sistema de ventanaslocal,locualpuederestringirsuaparienciayfuncionalidad. La clase Component (paquete java.awt) declara muchos de los atributos y comportamientos comunes para los componentesdeGUIenlospaquetesjava.awtyjavax.swing.

La clase Container (paquete java.awt) es una subclase de Component. Los objetos Component se adjuntan a los objetos Container,demaneraquepuedanorganizarseymostrarseenlapantalla. La clase JComponent (paquete javax.swing) es una subclase de Container. JComponent es la superclase de todos los componentesligerosdeSwing,ydeclaralosatributosycomportamientoscomunes. Algunas de las caractersticas comunes de JComponent son: una apariencia visual adaptable, teclas de mtodo abreviado llamadas nemnicos, cuadros de informacin sobre herramientas, soporte para tecnologas de ayuda y soporte para la localizacindelainterfazdeusuario.

11.4Mostrartextoeimgenesenunaventana
LamayoradelasventanassoninstanciasdelaclaseJFrameounasubclasedeJFrame.JFrameproporcionalosatributosy comportamientosbsicosdeunaventana. Un objeto JLabel muestra una sola lnea de texto de slo lectura, una imagen, o texto y una imagen. Por lo general, el textoenunobjetoJLabelusalacapitalizacinestilooracin. Al crear una GUI, cada componente de sta debe adjuntarse a un contenedor, como una ventana creada con un objeto JFrame. Muchos IDEs proporcionan herramientas de diseo de GUIs, en las cuales podemos especificar el tamao y la ubicacin exactosdeuncomponentemedianteelusodelratn,ydespuselIDEgeneraelcdigodelaGUIpornosotros. ElmtodosetToolTipTextdeJComponentespecificalainformacinsobreherramientasquesemuestracuandoelusuario colocaelcursordelratnsobreuncomponenteligero. ElmtodoadddeContaineradjuntauncomponentedeGUIaunobjetoContainer. LaclaseImageIcon(paquetejavax.swing)soportavariosformatosdeimagen,incluyendoGIF,PNGyJPEG. El mtodo getClass (de la clase Object) obtiene una referencia al objeto Class que representa la declaracin de la clase paraelobjetoenelquesehacelallamadaalmtodo. El mtodo getResource de Class devuelve la ubicacin de su argumento en forma de URL. El mtodo getResource usa el cargadordeclasesdelobjetoClassparadeterminarlaubicacindelrecurso. LainterfazSwingConstants(paquetejavax.swing)declaraunconjuntodeconstantesenterascomunesqueseutilizancon muchoscomponentesdeSwing. Las alineaciones horizontal y vertical de un objeto JLabel se pueden establecer mediante los mtodos setHorizontalAlignmentysetVerticalAlignment,respectivamente. El mtodo setText de JLabel establece el texto a mostrar en una etiqueta. El correspondiente mtodo getText obtiene el textoactualquesemuestraenunaetiqueta. ElmtodosetIcondeJLabelespecificaelobjetoIconamostrarenunaetiqueta.Elcorrespondientemtodo getIconobtieneelobjetoIconactualquesemuestraenunaetiqueta. Los mtodos setHorizontalTextPosition y setVerticalTextPosition de JLabel especifican la posicin del texto en la etiqueta. ElmtodosetDefaultCloseOperationdeJFrame,conlaconstanteJFrame.EXIT_ON_CLOSEcomoargumento,indicaqueel programadebeterminarcuandoelusuariocierrelaventana. ElmtodosetSizedeComponentespecificalaanchuraylaalturadeuncomponente. ElmtodosetVisibledeComponentconelargumentotruemuestraunobjetoJFrameenlapantalla.

//Fig.11.6:LabelFrame.javaDemostracindelaclaseJLabel. importjava.awt.FlowLayout;//especificacmosevanaordenarloscomponentes importjavax.swing.JFrame;//proporcionalascaractersticasbsicasdeunaventana importjavax.swing.JLabel;//muestratextoeimgenes importjavax.swing.SwingConstants;//constantescomunesutilizadasconSwing importjavax.swing.Icon;//interfazutilizadaparamanipularimgenes importjavax.swing.ImageIcon;//cargalasimgenes

publicclassLabelFrameextendsJFrame{ privateJLabeletiqueta1;//JLabelslocontexto privateJLabeletiqueta2;//JLabelconstruidacontextoyunicono privateJLabeletiqueta3;//JLabelcontextoadicionaleicono

//ElconstructordeLabelFrameagregaobjetosJLabelaJFrame publicLabelFrame(){ super("PruebadeJLabel"); setLayout(newFlowLayout());//estableceelesquemadelmarco

//ConstructordeJLabelconunargumentoString etiqueta1=newJLabel("Etiquetacontexto"); etiqueta1.setToolTipText("Estaesetiqueta1"); add(etiqueta1);//agregaetiqueta1aJFrame

//ConstructordeJLabelconargumentosdecadena,Iconoyalineacin Iconinsecto=newImageIcon(getClass().getResource("insecto1.gif")); etiqueta2=newJLabel("Etiquetacontextoeicono",insecto, SwingConstants.LEFT); etiqueta2.setToolTipText("Estaesetiqueta2"); add(etiqueta2);//agregaetiqueta2aJFrame

etiqueta3=newJLabel();//ConstructordeJLabelsinargumentos etiqueta3.setText("Etiquetaconiconoytextoenlaparteinferior"); etiqueta3.setIcon(insecto);//agregaiconoaJLabel etiqueta3.setHorizontalTextPosition(SwingConstants.CENTER); etiqueta3.setVerticalTextPosition(SwingConstants.BOTTOM); etiqueta3.setToolTipText("Estaesetiqueta3"); add(etiqueta3);//agregaetiqueta3aJFrame

}//findelconstructordeLabelFrame }//findelaclaseLabelFrame //Fig.11.7:PruebaLabel.javaPruebadeLabelFrame. importjavax.swing.JFrame;

publicclassPruebaLabel{ publicstaticvoidmain(Stringargs[]){ LabelFramemarcoEtiqueta=newLabelFrame();//creaobjetoLabelFrame marcoEtiqueta.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoEtiqueta.setSize(275,180);//estableceeltamaodelmarco marcoEtiqueta.setVisible(true);//muestraelmarco

}//findemain }//findelaclasePruebaLabel

LasGUIssecontrolanporeventos;cuandoelusuariointeractaconuncomponentedeGUI,loseventoscontrolan alprogramapararealizarlastareas. Elcdigoquerealizaunatareaenrespuestaauneventosellamamanejadordeeventos,yelprocesogeneralde responderaloseventosseconocecomomanejodeeventos. LaclaseJTextFieldextiendealaclaseJTextComponent(paquetejavax.swing.text),queproporcionamuchas caractersticascomunesparaloscomponentesdeSwingbasadosentexto.LaclaseJPasswordFieldextiendea JTextFieldyagregavariosmtodosespecficosparaelprocesamientodecontraseas. UnobjetoJPasswordFieldmuestraqueseestnescribiendocaracteresamedidaqueelusuariolosintroduce,pero ocultaloscaracteresrealesconcaracteresdeeco. Uncomponenterecibeelenfoquecuandoelusuariohaceclicsobrel. ElmtodosetEditabledeJTextComponentpuedeusarseparahacerqueuncampodetextonopuedaeditarse. AntesdequeunaaplicacinpuedaresponderauneventoparauncomponenteespecficodelaGUI,debemos realizarvariospasosdecodificacin:1)Crearunaclasequerepresentealmanejadordeeventos.2)Implementar unainterfazapropiada,conocidacomointerfazdeescuchadeeventos,enlaclasedelpaso1.3)Indicarquesedebe notificaraunobjetodelaclasedelospasos1y2cuandoocurraelevento.Aestoseleconocecomoregistrarel manejadordeeventos. Lasclasesanidadaspuedenserstaticonostatic.Lasclasesanidadasnostaticsellamanclasesinternas,yseutilizan confrecuenciaparaelmanejodeeventos. Antesdepodercrearunobjetodeunaclaseinterna,debehaberprimerounobjetodelaclasedenivelsuperior, quecontengaalaclaseinterna,yaqueunobjetodelaclaseinternatienedemaneraimplcitaunareferenciaaun objetodesuclasedenivelsuperior. Unobjetodelaclaseinternapuedeaccederdirectamenteatodaslasvariablesdeinstanciaymtodosdesuclase denivelsuperior. Unaclaseanidadaqueseastaticnorequiereunobjetodesuclasedenivelsuperior,ynotienedemaneraimplcita unareferenciaaunobjetodelaclasedenivelsuperior. CuandoelusuariooprimeIntroenunobjetoJTextFieldoJPasswordField,elcomponentedelaGUIgeneraun eventoActionEvent(paquetejava.awt.event).Dichoeventoseprocesamedianteunobjetoqueimplementaala interfazActionListener(paquetejava.awt.event). ElmtodoaddActionListenerdeJTextFieldregistraelmanejadordeeventosparauncampodetextodeun componente.EstemtodorecibecomoargumentounobjetoActionListener. ElcomponentedeGUIconelqueinteractaelusuarioeselorigendelevento. UnobjetoActionEventcontieneinformacinacercadeleventoqueacabadeocurrir,comoelorigendeleventoyel textoenelcampodetexto. ElmtodogetSourcedeActionEventdevuelveunareferenciaalorigendelevento.ElmtodogetActionCommand deActionEventdevuelveeltextoqueescribielusuarioenuncampodetextooenlaetiquetadeunobjeto JButton. ElmtodogetPassworddeJPasswordFielddevuelvelacontraseaqueescribielusuario.

11.5Camposdetextoyunaintroduccinalmanejodeeventosconclasesanidadas

//Fig.11.9:CampoTextoMarco.javaDemostracindelaclaseJTextField. importjava.awt.FlowLayout; importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.JFrame; importjavax.swing.JTextField; importjavax.swing.JPasswordField; importjavax.swing.JOptionPane; publicclassCampoTextoMarcoextendsJFrame{ privateJTextFieldcampoTexto1;//campodetextocontamaofijo privateJTextFieldcampoTexto2;//campodetextoconstruidocontexto privateJTextFieldcampoTexto3;//campodetextocontextoytamao privateJPasswordFieldcampoContrasenia;//campodecontraseacontexto //ElconstructordeCampoTextoMarcoagregaobjetosJTextFieldaJFrame publicCampoTextoMarco(){ super("PruebadeJTextFieldyJPasswordField"); setLayout(newFlowLayout());//estableceelesquemadelmarco //construyecampodetextocon10columnas campoTexto1=newJTextField(10); add(campoTexto1);//agregacampoTexto1aJFrame //construyecampodetextocontextopredeterminado campoTexto2=newJTextField("Escribaeltextoaqui"); add(campoTexto2);//agregacampoTexto2aJFrame //construyecampodetextocontextopredeterminadoy21columnas campoTexto3=newJTextField("Campodetextonoeditable",21); campoTexto3.setEditable(false);//deshabilitalaedicin add(campoTexto3);//agregacampoTexto3aJFrame //construyecampodecontraseacontextopredeterminado campoContrasenia=newJPasswordField("Textooculto"); add(campoContrasenia);//agregacampoContraseniaaJFrame //registralosmanejadoresdeeventos ManejadorCampoTextomanejador=newManejadorCampoTexto(); campoTexto1.addActionListener(manejador); campoTexto2.addActionListener(manejador); campoTexto3.addActionListener(manejador); campoContrasenia.addActionListener(manejador); }//findelconstructordeCampoTextoMarco //claseinternaprivadaparaelmanejodeeventos privateclassManejadorCampoTextoimplementsActionListener{ //procesaloseventosdecampodetexto publicvoidactionPerformed(ActionEventevento){ Stringcadena="";//declaralacadenaamostrar //elusuariooprimiIntroenelobjetoJTextFieldcampoTexto1 if(evento.getSource()==campoTexto1) cadena=String.format("campoTexto1:%s",evento.getActionCommand()); //elusuariooprimiIntroenelobjetoJTextFieldcampoTexto2 elseif(evento.getSource()==campoTexto2) cadena=String.format("campoTexto2:%s", evento.getActionCommand()); Figura 11.9 | Objetos JTextField y JPasswordField. (Parte 1 de 2).

//elusuariooprimiIntroenelobjetoJTextFieldcampoTexto3 elseif(evento.getSource()==campoTexto3) cadena=String.format("campoTexto3:%s", evento.getActionCommand()); //elusuariooprimiIntroenelobjetoJTextFieldcampoContrasenia elseif(evento.getSource()==campoContrasenia) cadena=String.format("campoContrasenia:%s", newString(campoContrasenia.getPassword())); //muestraelcontenidodelobjetoJTextField JOptionPane.showMessageDialog(null,cadena); }//findelmtodoactionPerformed }//findelaclaseinternaprivadaManejadorCampoTexto }//findelaclaseCampoTextoMarco Figura 11.9 | Objetos JTextField y JPasswordField. (Parte 2 de 2). //Fig.11.10:PruebaCampoTexto.javaPruebadeCampoTextoMarco. importjavax.swing.JFrame; publicclassPruebaCampoTexto{ publicstaticvoidmain(Stringargs[]){ CampoTextoMarcocampoTextoMarco=newCampoTextoMarco(); campoTextoMarco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); campoTextoMarco.setSize(350,100);//estableceeltamaodelmarco campoTextoMarco.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaCampoTexto

Para cada tipo de objeto evento hay, por lo general, una interfaz de escucha de eventos que le corresponde. Cada interfaz de escucha de eventos especifica uno o ms mtodos manejadores de eventos, que deben declararse en la clasequeimplementaalainterfaz.

11.6TiposdeeventoscomunesdelaGUIeinterfacesdeescucha

Figura11.11|Algunasclasesdeeventosdelpaquetejava.awt.event.

11.7Cmofuncionaelmanejodeeventos
Cuando ocurre un evento, el componente de la GUI con el que el usuario interactu notifica a sus componentes de escucharegistrados,llamandoalmtododemanejodeeventosapropiadodecadacomponentedeescucha. TodoobjetoJComponenttieneunavariabledeinstanciallamadalistenerList,lacualhacereferenciaaunobjetode la clase EventListenerList (paquete javax.swing.event). Cada objeto de una subclase de JComponent mantiene las referenciasatodossuscomponentesdeescucharegistradosenlavariablelistenerList. Todo componente de la GUI soporta varios tipos de eventos, incluyendo los eventos de ratn, de teclado y otros. Cuando ocurre un evento, ste se despacha slo a los componentes de escucha de eventos del tipo apropiado. El componente de la GUI recibe un ID de evento nico, especificando el tipo de evento, el cual utiliza para decidir el tipo de componente de escucha al que debe despacharse el evento, y cul mtodo llamar en cada objeto componentedeescucha.

11.8JButton

Un botn es un componente en el que el usuario hace clic para desencadenar cierta accin. Todos los tipos de botonessonsubclasesdeAbstractButton(paquetejavax.swing),lacualdeclaralascaractersticascomunesparalos botonesdeSwing.Porlogeneral,lasetiquetasdelosbotonesusanlacapitalizacintipottulodelibro;unestiloque capitalizalaprimeraletradecadapalabrasignificativaeneltexto,ynoterminaconningnsignodepuntuacin. LosbotonesdecomandossecreanconlaclaseJButton. Un objeto JButton puede mostrar un objeto Icon. Para proporcionar al usuario un nivel adicional de interaccin visual con la GUI, un objeto JButton tambin puede tener un icono de sustitucin: un objeto Icon que se muestra cuandoelusuariocolocaelratnsobreelbotn. El mtodo setRolloverIcon (de la clase AbstractButton) especifica la imagen a mostrar en un botn, cuando el usuariocolocaelratnsobrel.

//Fig.11.15:MarcoBoton.java //CreacindeobjetosJButton. importjava.awt.FlowLayout; importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.JFrame; importjavax.swing.JButton; importjavax.swing.Icon; importjavax.swing.ImageIcon; importjavax.swing.JOptionPane; publicclassMarcoBotonextendsJFrame{ privateJButtonbotonJButtonSimple;//botncontextosolamente privateJButtonbotonJButtonElegante;//botnconiconos //MarcoBotonagregaobjetosJButtonaJFrame publicMarcoBoton(){ super("Pruebadebotones"); setLayout(newFlowLayout());//estableceelesquemadelmarco botonJButtonSimple=newJButton("Botonsimple");//botncontexto add(botonJButtonSimple);//agregabotonJButtonSimpleaJFrame Iconinsecto1=newImageIcon(getClass().getResource("insecto1.gif")); Iconinsecto2=newImageIcon(getClass().getResource("insecto2.gif")); botonJButtonElegante=newJButton("Botonelegante",insecto1);//establecelaimagen botonJButtonElegante.setRolloverIcon(insecto2);//establecelaimagendesustitucin add(botonJButtonElegante);//agregabotonJButtonEleganteaJFrame //creanuevoManejadorBotonparamanejarloseventosdebotn ManejadorBotonmanejador=newManejadorBoton(); botonJButtonElegante.addActionListener(manejador); botonJButtonSimple.addActionListener(manejador); }//findelconstructordeMarcoBoton //claseinternaparamanejareventosdebotn privateclassManejadorBotonimplementsActionListener{ //manejaeventodebotn publicvoidactionPerformed(ActionEventevento){ JOptionPane.showMessageDialog(MarcoBoton.this,String.format( "Ustedoprimio:%s",evento.getActionCommand())); }//findelmtodoactionPerformed }//findelaclaseinternaprivadaManejadorBoton }//findelaclaseMarcoBoton

//Fig.11.16:PruebaBoton.javaPruebadeMarcoBoton. importjavax.swing.JFrame; publicclassPruebaBoton{ publicstaticvoidmain(Stringargs[]){ MarcoBotonmarcoBoton=newMarcoBoton();//creaMarcoBoton marcoBoton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoBoton.setSize(300,110);//estableceeltamaodelmarco marcoBoton.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaBoton

11.9Botonesquemantienenelestado

Los componentes de la GUI de Swing contienen tres tipos de botones de estado: JToggleButton, JCheckBox y JRadioButton. Las clases JCheckBox y JRadioButton son subclases de JToggleButton. Un objeto JRadioButton es distinto de un objeto JCheckBox en cuanto a que, generalmente, hay varios objetos JRadioButton que se agrupan, y slo puede seleccionarseunbotnenelgrupo,enunmomentodado. El mtodo setFont (de la clase Component) establece el tipo de letra de un componente a un nuevo objeto de la claseFont(paquetejava.awt). Cuando el usuario hace clic en un objeto JCheckBox, ocurre un evento ItemEvent. Este evento puede manejarse medianteunobjetoItemListener,quedebeimplementaralmtodoitemStateChanged.ElmtodoaddItemListener registraelcomponentedeescuchaparaunobjetoJCheckBoxoJRadioButton. ElmtodoisSelecteddeJCheckBoxdeterminasiunobjetoJCheckBoxestseleccionado. LosobjetosJRadioButtonsonsimilaresalosobjetosJCheckBoxencuantoaquetienendosestados:seleccionadoy noseleccionado.Sinembargo,generalmentelosbotonesdeopcinaparecencomoungrupo,enelcualslopuede seleccionarseunbotnalavez.Alseleccionarunbotndeopcindistinto,seobligaalosdemsbotonesdeopcin adeseleccionarse. LosobjetosJRadioButtonseutilizanpararepresentaropcionesmutuamenteexclusivas. La relacin lgica entre los objetos JRadioButton se mantiene mediante un objeto ButtonGroup (paquete javax.swing). ElmtodoadddeButtonGroupasociaacadaobjetoJRadioButtonconunobjetoButtonGroup.Siseagregamsde un objeto JRadioButton seleccionado a un grupo, el primer objeto JRadioButton seleccionado que se agregue ser elquequedeseleccionadocuandosemuestrelaGUIenpantalla. LosobjetosJRadioButtongeneraneventosItemEventcuandosehaceclicsobreellos.

//Fig.11.17:MarcoCasillaVerificacion.javaCreacindebotonesJCheckBox. importjava.awt.FlowLayout; importjava.awt.Font; importjava.awt.event.ItemListener; importjava.awt.event.ItemEvent; importjavax.swing.JFrame; importjavax.swing.JTextField; importjavax.swing.JCheckBox; publicclassMarcoCasillaVerificacionextendsJFrame{ privateJTextFieldcampoTexto;//muestraeltextoentiposdeletracambiantes privateJCheckBoxnegritaJCheckBox;//paraseleccionar/deseleccionarnegrita privateJCheckBoxcursivaJCheckBox;//paraseleccionar/deseleccionarcursiva //ElconstructordeMarcoCasillaVerificacionagregaobjetosJCheckBoxaJFrame publicMarcoCasillaVerificacion() { super("PruebadeJCheckBox"); setLayout(newFlowLayout());//estableceelesquemadelmarco //estableceJTextFieldysutipodeletra campoTexto=newJTextField("Observecomocambiaelestilodetipodeletra",28); campoTexto.setFont(newFont("Serif",Font.PLAIN,14)); add(campoTexto);//agregacampoTextoaJFrame negritaJCheckBox=newJCheckBox("Negrita");//creacasilladeverificacin"negrita" cursivaJCheckBox=newJCheckBox("Cursiva");//creacasilladeverificacin"cursiva" add(negritaJCheckBox);//agregacasilladeverificacin"negrita"aJFrame add(cursivaJCheckBox);//agregacasilladeverificacin"cursiva"aJFrame //registracomponentesdeescuchaparaobjetosJCheckBox ManejadorCheckBoxmanejador=newManejadorCheckBox(); negritaJCheckBox.addItemListener(manejador); cursivaJCheckBox.addItemListener(manejador); }//findelconstructordeMarcoCasillaVerificacion //claseinternaprivadaparaelmanejodeeventosItemListener privateclassManejadorCheckBoximplementsItemListener { privateintvalNegrita=Font.PLAIN;//controlaelestilodetipodeletranegrita privateintvalCursiva=Font.PLAIN;//controlaelestilodetipodeletracursiva //respondealoseventosdecasilladeverificacin publicvoiditemStateChanged(ItemEventevento){ //procesaloseventosdelacasilladeverificacin"negrita" if(evento.getSource()==negritaJCheckBox) valNegrita= negritaJCheckBox.isSelected()?Font.BOLD:Font.PLAIN; //procesaloseventosdelacasilladeverificacin"cursiva" if(evento.getSource()==cursivaJCheckBox) valCursiva= cursivaJCheckBox.isSelected()?Font.ITALIC:Font.PLAIN; //estableceeltipodeletradelcampodetexto campoTexto.setFont(newFont("Serif",valNegrita+valCursiva,14)); }//findelmtodoitemStateChanged }//findelaclaseinternaprivadaManejadorCheckBox }//findelaclaseMarcoCasillaVerificacion

//Fig.11.18:PruebaCasillaVerificacion.javaPruebadeMarcoCasillaVerificacion. importjavax.swing.JFrame; publicclassPruebaCasillaVerificacion{ publicstaticvoidmain(Stringargs[]){ MarcoCasillaVerificacionmarcoCasillaVerificacion=newMarcoCasillaVerificacion(); marcoCasillaVerificacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoCasillaVerificacion.setSize(350,100);//estableceeltamaodelmarco marcoCasillaVerificacion.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaCasillaVerificacion

11.9.2JRadioButton //Fig.11.19:MarcoBotonOpcion.javaCreacindebotonesdeopcin,usandoButtonGroupyJRadioButton. importjava.awt.FlowLayout; importjava.awt.Font; importjava.awt.event.ItemListener; importjava.awt.event.ItemEvent; importjavax.swing.JFrame; importjavax.swing.JTextField; importjavax.swing.JRadioButton; importjavax.swing.ButtonGroup; publicclassMarcoBotonOpcionextendsJFrame{ privateJTextFieldcampoTexto;//seutilizaparamostrarloscambioseneltipodeletra privateFonttipoLetraSimple;//tipodeletraparatextosimple privateFonttipoLetraNegrita;//tipodeletraparatextoennegrita privateFonttipoLetraCursiva;//tipodeletraparatextoencursiva privateFonttipoLetraNegritaCursiva;//tipodeletraparatextoennegritaycursiva privateJRadioButtonsimpleJRadioButton;//seleccionatextosimple privateJRadioButtonnegritaJRadioButton;//seleccionatextoennegrita privateJRadioButtoncursivaJRadioButton;//seleccionatextoencursiva privateJRadioButtonnegritaCursivaJRadioButton;//negritaycursiva privateButtonGroupgrupoOpciones;//grupodebotonesquecontienelosbotonesdeopcin //ElconstructordeMarcoBotonOpcionagregalosobjetosJRadioButtonaJFrame publicMarcoBotonOpcion(){ super("PruebadeRadioButton"); setLayout(newFlowLayout());//estableceelesquemadelmarco campoTexto=newJTextField("Observeelcambioenelestilodeltipodeletra",28); add(campoTexto);//agregacampoTextoaJFrame
Figura 11.19 | Objetos JRadioButton y ButtonGroup. (Parte 1 de 2).

//crealosbotonesdeopcin simpleJRadioButton=newJRadioButton("Simple",true); negritaJRadioButton=newJRadioButton("Negrita",false); cursivaJRadioButton=newJRadioButton("Cursiva",false); negritaCursivaJRadioButton=newJRadioButton("Negrita/Cursiva",false); add(simpleJRadioButton);//agregabotnsimpleaJFrame add(negritaJRadioButton);//agregabotnnegritaaJFrame add(cursivaJRadioButton);//agregabotncursivaaJFrame add(negritaCursivaJRadioButton);//agregabotnnegritaycursiva //creaunarelacinlgicaentrelosobjetosJRadioButton grupoOpciones=newButtonGroup();//creaButtonGroup grupoOpciones.add(simpleJRadioButton);//agregasimplealgrupo grupoOpciones.add(negritaJRadioButton);//agreganegritaalgrupo grupoOpciones.add(cursivaJRadioButton);//agregacursivaalgrupo grupoOpciones.add(negritaCursivaJRadioButton);//agreganegritaycursiva //creaobjetostipodeletra tipoLetraSimple=newFont("Serif",Font.PLAIN,14); tipoLetraNegrita=newFont("Serif",Font.BOLD,14); tipoLetraCursiva=newFont("Serif",Font.ITALIC,14); tipoLetraNegritaCursiva=newFont("Serif",Font.BOLD+Font.ITALIC,14); campoTexto.setFont(tipoLetraSimple);//establecetipoletrainicialasimple //registraeventosparalosobjetosJRadioButton simpleJRadioButton.addItemListener(newManejadorBotonOpcion(tipoLetraSimple)); negritaJRadioButton.addItemListener(newManejadorBotonOpcion(tipoLetraNegrita)); cursivaJRadioButton.addItemListener(newManejadorBotonOpcion(tipoLetraCursiva)); negritaCursivaJRadioButton.addItemListener(newManejadorBotonOpcion(tipoLetraNegritaCursiva)); }//findelconstructordeMarcoBotonOpcion //claseinternaprivadaparamanejareventosdebotonesdeopcin privateclassManejadorBotonOpcionimplementsItemListener{ privateFonttipoLetra;//tipodeletraasociadoconestecomponentedeescucha publicManejadorBotonOpcion(Fontf){ tipoLetra=f;//estableceeltipodeletradeestecomponentedeescucha }//findelconstructorManejadorBotonOpcion //manejaloseventosdebotonesdeopcin publicvoiditemStateChanged(ItemEventevento){ campoTexto.setFont(tipoLetra);//estableceeltipodeletradecampoTexto }//findelmtodoitemStateChanged }//findelaclaseinternaprivadaManejadorBotonOpcion }//findelaclaseMarcoBotonOpcion

Figura 11.19 | Objetos JRadioButton y ButtonGroup. (Parte 1 de 2).


//Fig.11.20:PruebaBotonOpcion.javaPruebadeMarcoBotonOpcion. importjavax.swing.JFrame; publicclassPruebaBotonOpcion{ publicstaticvoidmain(Stringargs[]){ MarcoBotonOpcionmarcoBotonOpcion=newMarcoBotonOpcion(); marcoBotonOpcion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoBotonOpcion.setSize(350,100);//estableceeltamaodelmarco marcoBotonOpcion.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaBotonOpcion

11.10JComboBoxyelusodeunaclaseinternaannimaparaelmanejodeeventos

Un objeto JComboBox proporciona una lista de elementos, de los cuales el usuario puede seleccionar uno. Los objetosJComboBoxgeneraneventosItemEvent. CadaelementoenunobjetoJComboBoxtieneunndice.ElprimerelementoqueseagregaaunobjetoJComboBox aparececomoelelementoactualmenteseleccionadocuandosemuestraelobjetoJComboBox.Losotroselementos se seleccionan haciendo clic en el objeto JComboBox, el cual se expande en una lista, de la cual el usuario puede seleccionarunelemento. El mtodo setMaximumRowCount de JComboBox establece el mximo nmero de elementos a mostrar cuando el usuario haga clic en el objeto JComboBox. Si hay elementos adicionales, el objeto JComboBox proporciona una barradedesplazamientoquepermitealusuariodesplazarseportodosloselementosenlalista. Una clase interna annima es una forma especial de clase interna, que se declara sin un nombre y por lo general aparecedentro de la declaracin deun mtodo. Como una clase interna annima no tiene nombre, un objeto de la claseinternaannimadebecrearseenelpuntoenelquesedeclaralaclase. ElmtodogetSelectedIndexdeJcomboBoxdevuelveelndicedelelementoseleccionado.

//Fig.11.21:MarcoCuadroCombinado.javaUsodeunobjetoJComboBoxparaseleccionarunaimagenamostrar. importjava.awt.FlowLayout; importjava.awt.event.ItemListener; importjava.awt.event.ItemEvent; importjavax.swing.JFrame; importjavax.swing.JLabel; importjavax.swing.JComboBox; importjavax.swing.Icon; importjavax.swing.ImageIcon; publicclassMarcoCuadroCombinadoextendsJFrame{ privateJComboBoximagenesJComboBox;//cuadrocombinadoconlosnombresdelosiconos privateJLabeletiqueta;//etiquetaparamostrareliconoseleccionado privateStringnombres[]={"insecto1.gif","insecto2.gif","insectviaje.gif","insectanim.gif"}; privateIconiconos[]={ newImageIcon(getClass().getResource(nombres[0])), newImageIcon(getClass().getResource(nombres[1])), newImageIcon(getClass().getResource(nombres[2])), newImageIcon(getClass().getResource(nombres[3]))}; //ElconstructordeMarcoCuadroCombinadoagregaunobjetoJComboBoxaJFrame publicMarcoCuadroCombinado(){ super("PruebadeJComboBox"); setLayout(newFlowLayout());//estableceelesquemadelmarco

Figura 11.21 | Objeto JComboBox que muestra una lista de nombres de imgenes. (Parte 1 de 2).

imagenesJComboBox=newJComboBox(nombres);//estableceJComboBox imagenesJComboBox.setMaximumRowCount(3);//muestratresfilas imagenesJComboBox.addItemListener( newItemListener()//claseinternaannima { //manejaeventodeJComboBox publicvoiditemStateChanged(ItemEventevento){ //determinasiestseleccionadalacasilladeverificacin if(evento.getStateChange()==ItemEvent.SELECTED) etiqueta.setIcon(iconos[ imagenesJComboBox.getSelectedIndex()]); }//findelmtodoitemStateChanged }//findelaclaseinternaannima );//findelallamadaaaddItemListener add(imagenesJComboBox);//agregacuadrocombinadoaJFrame etiqueta=newJLabel(iconos[0]);//muestraelprimericono add(etiqueta);//agregaetiquetaaJFrame

}//findelconstructordeMarcoCuadroCombinado }//findelaclaseMarcoCuadroCombinado

Figura 11.21 | Objeto JComboBox que muestra una lista de nombres de imgenes. (Parte 2 de 2).
//Fig.11.22:PruebaCuadroCombinado.javaPruebadeMarcoCuadroCombinado. importjavax.swing.JFrame; publicclassPruebaCuadroCombinado{ publicstaticvoidmain(Stringargs[]){ MarcoCuadroCombinadomarcoCuadroCombinado=newMarcoCuadroCombinado(); marcoCuadroCombinado.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoCuadroCombinado.setSize(350,150);//estableceeltamaodelmarco marcoCuadroCombinado.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaCuadroCombinado

11.11JList
UnobjetoJListmuestraunaseriedeelementos,deloscualeselusuariopuedeseleccionarunooms.LaclaseJList soportalaslistasdeseleccinsimpleydeseleccinmltiple. Cuando el usuario haceclic en un elemento de un objeto JList, se produce un eventoListSelectionEvent. El mtodo addListSelectionListener registra un objeto ListSelectionListener para los eventos de seleccin de un objeto JList. UnobjetoListSelectionListener(paquetejavax.swing.event)debeimplementarelmtodovalueChanged. ElmtodosetVisibleRowCountdeJListespecificaelnmerodeelementosvisiblesenlalista. ElmtodosetSelectionModedeJListespecificaelmododeseleccindeunalista. UnobjetoJListnoproporcionaunabarradedesplazamientosihaymselementosenlalistaqueelnmerodefilas visibles. En este caso, puede usarse un objeto JScrollPane para proporcionar la capacidad de desplazamiento. El mtodo getContentPane de JFrame devuelve una referencia al panel de contenido de JFrame, en donde se muestranloscomponentesdelaGUI. ElmtodogetSelectedIndexdeJListdevuelveelndicedelelementoseleccionado.

//Fig.11.23:MarcoLista.javaSeleccindecoloresdeunobjetoJList. importjava.awt.FlowLayout; importjava.awt.Color; importjavax.swing.JFrame; importjavax.swing.JList; importjavax.swing.JScrollPane; importjavax.swing.event.ListSelectionListener; importjavax.swing.event.ListSelectionEvent; importjavax.swing.ListSelectionModel; publicclassMarcoListaextendsJFrame{ privateJListlistaJListColores;//listaparamostrarcolores privatefinalStringnombresColores[]={"Negro","Azul","Cyan","Grisoscuro","Gris","Verde","Grisclaro","Magenta", "Naranja","Rosa","Rojo","Blanco","Amarillo"}; privatefinalColorcolores[]={Color.BLACK,Color.BLUE,Color.CYAN, Color.DARK_GRAY,Color.GRAY,Color.GREEN,Color.LIGHT_GRAY, Color.MAGENTA,Color.ORANGE,Color.PINK,Color.RED,Color.WHITE, Color.YELLOW}; //ElconstructordeMarcoListaagregaaJFrameelJScrollPanequecontieneaJList publicMarcoLista(){ super("PruebadeJList"); setLayout(newFlowLayout());//estableceelesquemadelmarco listaJListColores=newJList(nombresColores);//creaconnombresColores listaJListColores.setVisibleRowCount(5);//muestracincofilasalavez //nopermiteseleccionesmltiples listaJListColores.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //agregaalmarcounobjetoJScrollPanequecontieneaJList add(newJScrollPane(listaJListColores)); listaJListColores.addListSelectionListener(newListSelectionListener()//claseinternaannima { //manejaloseventosdeseleccindelalista publicvoidvalueChanged(ListSelectionEventevento){ getContentPane().setBackground( colores[listaJListColores.getSelectedIndex()]);

}//findelmtodovalueChanged }//findelaclaseinternaannima );//findelallamadaaaddListSelectionListener }//findelconstructordeMarcoLista }//findelaclaseMarcoLista

//Fig.11.24:PruebaLista.javaSeleccindecoloresdeunobjetoJList. importjavax.swing.JFrame; publicclassPruebaLista{ publicstaticvoidmain(Stringargs[]){ MarcoListamarcoLista=newMarcoLista();//creaobjetoMarcoLista marcoLista.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoLista.setSize(350,150);//estableceeltamaodelmarco marcoLista.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaLista

11.12Listasdeseleccinmltiple

UnalistadeseleccinmltiplepermitealusuarioseleccionarmuchoselementosdeunobjetoJList. El mtodo setFixedCellWidth de JList establece la anchura de un objeto JList. El mtodo setFixedCellHeight establecelaalturadecadaelementoenunobjetoJList. Nohayeventosparaindicarqueunusuarioharealizadovariasseleccionesenunalistadeseleccinmltiple.Porlo general, un evento externo generado por otro componente de la GUI especifica cundo deben procesarse las seleccionesmltiplesenunobjetoJList. El mtodo setListData de JList establece los elementos a mostrar en un objeto JList. El mtodo getSelectedValues deJListdevuelveunarreglodeobjetosObjectquerepresentanloselementosseleccionadosenunobjetoJList.

//Fig.11.25:MarcoSeleccionMultiple.javaCopiarelementosdeunobjetoListaotro. importjava.awt.FlowLayout; importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.JFrame; importjavax.swing.JList; importjavax.swing.JButton; importjavax.swing.JScrollPane; importjavax.swing.ListSelectionModel; publicclassMarcoSeleccionMultipleextendsJFrame{ privateJListlistaJListColores;//listaparaguardarlosnombresdeloscolores privateJListlistaJListCopia;//listaenlaquesevanacopiarlosnombresdeloscolores privateJButtonbotonJButtonCopiar;//botnparacopiarlosnombresseleccionados privatefinalStringnombresColores[]={"Negro","Azul","Cyan","Grisoscuro","Gris","Verde","Grisclaro","Magenta", "Naranja","Rosa","Rojo","Blanco","Amarillo"}; //ConstructordeMarcoSeleccionMultiple publicMarcoSeleccionMultiple(){ super("Listasdeseleccionmultiple"); setLayout(newFlowLayout());//estableceelesquemadelmarco

Figura 11.25 | Objeto JList que permite selecciones mltiples. (Parte 1 de 2).

listaJListColores=newJList(nombresColores);//contienenombresdetodosloscolores listaJListColores.setVisibleRowCount(5);//muestracincofilas listaJListColores.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); add(newJScrollPane(listaJListColores));//agregalistaconpaneldedesplazamiento botonJButtonCopiar=newJButton("Copiar>>>");//creabotnparacopiar botonJButtonCopiar.addActionListener( newActionListener()//claseinternaannima { //manejaeventodebotn publicvoidactionPerformed(ActionEventevento) { //colocalosvaloresseleccionadosenlistaJListCopia listaJListCopia.setListData(listaJListColores.getSelectedValues()); }//findelmtodoactionPerformed }//findelaclaseinternaannima );//findelallamadaaaddActionListener add(botonJButtonCopiar);//agregaelbotncopiaraJFrame listaJListCopia=newJList();//crealistaparaguardarnombresdecolorescopiados listaJListCopia.setVisibleRowCount(5);//muestra5filas listaJListCopia.setFixedCellWidth(100);//establecelaanchura listaJListCopia.setFixedCellHeight(15);//establecelaaltura listaJListCopia.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); add(newJScrollPane(listaJListCopia));//agregalistaconpaneldedesplazamiento }//findelconstructordeMarcoSeleccionMultiple }//findelaclaseMarcoSeleccionMultiple

Figura 11.25 | Objeto JList que permite selecciones mltiples. (Parte 2 de 2).
//Fig.11.26:PruebaSeleccionMultiple.javaPruebadeMarcoSeleccionMultiple. importjavax.swing.JFrame; publicclassPruebaSeleccionMultiple{ publicstaticvoidmain(Stringargs[]){ MarcoSeleccionMultiplemarcoSeleccionMultiple= newMarcoSeleccionMultiple(); marcoSeleccionMultiple.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoSeleccionMultiple.setSize(350,140);//estableceeltamaodelmarco marcoSeleccionMultiple.setVisible(true);//muestraelmarco }//findemain }//findelaclasePruebaSeleccionMultiple

11.13Manejodeeventosdelratn
Las interfaces de escucha de eventos MouseListener y MouseMotionListener se utilizan para manejar los eventos delratn.EstoseventossepuedenatraparparacualquiercomponentedelaGUIqueextiendaaComponent. La interfaz MouseInputListener (paquete javax.swing.event) extiende a las interfaces MouseListener y MouseMotionListenerparacrearunasolainterfazquecontengaatodossusmtodos. Cada uno de los mtodos manejadores de eventos del ratn recibe un objeto MouseEvent como argumento. Un objeto MouseEvent contiene informacinacercadel evento de ratnque ocurri, incluyendo las coordenadas xyy de la ubicacin en donde ocurri el evento. Estas coordenadas se miden empezando desde la esquina superior izquierdadelcomponentedelaGUIendondeocurrielevento. LosmtodosyconstantesdelaclaseInputEvent(superclasedeMouseEvent)permitenaunaaplicacindeterminar culbotnoprimielusuario. LainterfazMouseWheelListenerpermitealasaplicacionesresponderalarotacindelaruedadeunratn. Los componentes de la GUI heredan los mtodos addMouseListener y addMouseMotionListener de la clase Component.

//Fig.11.28:MarcoRastreadorRaton.javaDemostracindeloseventosderatn. importjava.awt.Color; importjava.awt.BorderLayout; importjava.awt.event.MouseListener; importjava.awt.event.MouseMotionListener; importjava.awt.event.MouseEvent; importjavax.swing.JFrame; importjavax.swing.JLabel; importjavax.swing.JPanel; publicclassMarcoRastreadorRatonextendsJFrame{ privateJPanelpanelRaton;//panelenelqueocurrirnloseventosderatn privateJLabelbarraEstado;//etiquetaquemuestrainformacindeloseventos //ElconstructordeMarcoRastreadorRatonestablecelaGUIy //registralosmanejadoresdeeventosderatn publicMarcoRastreadorRaton(){ super("Demostraciondeloseventosderaton"); panelRaton=newJPanel();//creaelpanel panelRaton.setBackground(Color.WHITE);//estableceelcolordefondo add(panelRaton,BorderLayout.CENTER);//agregaelpanelaJFrame barraEstado=newJLabel("RatonfueradeJPanel"); add(barraEstado,BorderLayout.SOUTH);//agregaetiquetaaJFrame //creayregistrauncomponentedeescuchaparaloseventosderatnydesumovimiento ManejadorRatonmanejador=newManejadorRaton(); panelRaton.addMouseListener(manejador); panelRaton.addMouseMotionListener(manejador); }//findelconstructordeMarcoRastreadorRaton privateclassManejadorRatonimplementsMouseListener,MouseMotionListener{ //LosmanejadoresdeeventosdeMouseListener //manejaneleventocuandosesueltaelratnjustodespusdeoprimirelbotn publicvoidmouseClicked(MouseEventevento){ barraEstado.setText(String.format("Sehizoclicen[%d,%d]", evento.getX(),evento.getY())); }//findelmtodomouseClicked //manejaeventocuandoseoprimeelratn publicvoidmousePressed(MouseEventevento){ barraEstado.setText(String.format("Seoprimioen[%d,%d]", evento.getX(),evento.getY())); }//findelmtodomousePressed //manejaeventocuandosesueltaelbotndelratndespusdearrastrarlo publicvoidmouseReleased(MouseEventevento){ barraEstado.setText(String.format("Sesoltoen[%d,%d]", evento.getX(),evento.getY())); }//findelmtodomouseReleased //manejaeventocuandoelratnentraalrea publicvoidmouseEntered(MouseEventevento){ barraEstado.setText(String.format("Ratonentroen[%d,%d]", evento.getX(),evento.getY())); panelRaton.setBackground(Color.GREEN); }//findelmtodomouseEntered

Figura 11.28 | Manejo de eventos de ratn. (Parte 1 de 2).

//manejaeventocuandoelratnsaledelrea publicvoidmouseExited(MouseEventevento){ barraEstado.setText("RatonfueradeJPanel"); panelRaton.setBackground(Color.WHITE); }//findelmtodomouseExited //LosmanejadoresdeeventosdeMouseMotionListenermanejan //eleventocuandoelusuarioarrastraelratnconelbotnoprimido publicvoidmouseDragged(MouseEventevento){ barraEstado.setText(String.format("Searrastroen[%d,%d]", evento.getX(),evento.getY())); }//findelmtodomouseDragged

//manejaeventocuandoelusuariomueveelratn publicvoidmouseMoved(MouseEventevento){ barraEstado.setText(String.format("Semovioen[%d,%d]",evento.getX(),evento.getY()));

}//findelmtodomouseMoved }//findelaclaseinternaManejadorRaton }//findelaclaseMarcoRastreadorRaton

Figura 11.28 | Manejo de eventos de ratn. (Parte 1 de 2).


//Fig.11.29:MarcoRastreadorRaton.javaPruebadeMarcoRastreadorRaton. importjavax.swing.JFrame;

publicclassRastreadorRaton{ publicstaticvoidmain(Stringargs[]){ MarcoRastreadorRatonmarcoRastreadorRaton=newMarcoRastreadorRaton(); marcoRastreadorRaton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoRastreadorRaton.setSize(300,100);//estableceeltamaodelmarco marcoRastreadorRaton.setVisible(true);//muestraelmarco

}//findemain }//findelaclaseRastreadorRaton

11.14Clasesadaptadoras
Muchas interfaces de escucha de eventos contienen varios mtodos. Para muchas de estas interfaces, los paquetes java.awt.eventyjavax.swing.eventproporcionanclasesadaptadorasdeescuchadeeventos.Unaclaseadaptadora implementa a una interfaz y proporciona una implementacin predeterminada de cada mtodo en la interfaz. Podemos extender una clase adaptadora para que herede la implementacin predeterminada de cada mtodo, y porconsiguiente,podemossobrescribirsloel(los)mtodo(s)necesario(s)paraelmanejodeeventos.

El mtodo getClickCount de MouseEvent devuelve el nmero de clics de los botones del ratn. Los mtodos isMetaDowneisAltDowndeterminanculbotndelratnoprimielusuario.

//Fig.11.31:MarcoDetallesRaton.javaDemostracindelosclicsdelratnycmodiferenciarlosbotonesdelmismo. importjava.awt.BorderLayout; importjava.awt.Graphics; importjava.awt.event.MouseAdapter; importjava.awt.event.MouseEvent; importjavax.swing.JFrame; importjavax.swing.JLabel;

publicclassMarcoDetallesRatonextendsJFrame{ privateStringdetalles;//objetoStringquerepresentaalobjetoJLabel privateJLabelbarraEstado;//queapareceenlaparteinferiordelaventana

//constructorestableceStringdelabarradettuloyregistracomponentedeescuchadelratn publicMarcoDetallesRaton(){ super("Clicsybotonesdelraton");

barraEstado=newJLabel("Hagaclicenelraton"); add(barraEstado,BorderLayout.SOUTH); addMouseListener(newManejadorClicRaton());//agregaelmanejador }//findelconstructordeMarcoDetallesRaton //claseinternaparamanejarloseventosdelratn privateclassManejadorClicRatonextendsMouseAdapter{ //manejaeventodeclicdelratnydeterminaculbotnseoprimi publicvoidmouseClicked(MouseEventevento){ intxPos=evento.getX();//obtieneposicinxdelratn intyPos=evento.getY();//obtieneposicinydelratn

detalles=String.format("Sehizoclic%dvez(veces)",evento.getClickCount());

if(evento.isMetaDown())//botnderechodelratn detalles+="conelbotonderechodelraton"; elseif(evento.isAltDown())//botncentraldelratn detalles+="conelbotoncentraldelraton"; else//botnizquierdodelratn detalles+="conelbotonizquierdodelraton";

barraEstado.setText(detalles);//muestramensajeenbarraEstado

}//findelmtodomouseClicked }//findelaclaseinternaprivadaManejadorClicRaton }//findelaclaseMarcoDetallesRaton

//Fig.11.32:DetallesRaton.javaPruebadeMarcoDetallesRaton. importjavax.swing.JFrame; publicclassDetallesRaton{ publicstaticvoidmain(Stringargs[]){ MarcoDetallesRatonmarcoDetallesRaton=newMarcoDetallesRaton(); marcoDetallesRaton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoDetallesRaton.setSize(400,150);//estableceeltamaodelmarco marcoDetallesRaton.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDetallesRaton

Los componentes ligeros de Swing que extienden a la clase JComponent contienen el mtodo paintComponent, el cual se llama cuando se muestra un componente ligero de Swing. Al sobrescribir este mtodo, puede especificar cmodibujarfigurasusandolasherramientasdegrficosdeJava. Al personalizar un objeto JPanel para usarlo como un rea dedicada de dibujo, la subclase debe sobrescribir el mtodopaintComponenty llamar a la versin depaintComponentde la superclasecomo la primerainstruccin en elcuerpodelmtodosobrescrito. Las subclases de JComponent soportan la transparencia. Cuando un componente es opaco, paintComponent borra elfondodelcomponenteantesdemostrarloenpantalla.

11.15SubclasedeJPanelparadibujarconelratn

La transparencia de un componente ligero de Swing puede establecerse con el mtodo setOpaque (un argumento falseindicaqueelcomponenteestransparente). LaclasePoint(paquetejava.awt)representaunacoordenadaxy. LaclaseGraphicsseutilizaparadibujar. ElmtodogetPointdeMouseEventobtieneelobjetoPointendondeocurriuneventoderatn. Elmtodorepaint(heredadodirectamentedelaclaseComponent)indicaqueuncomponentedebeactualizarseen lapantallalomsprontoposible. El mtodo paintComponent recibe un parmetro Graphics, y se llama de manera automtica cada vez que un componenteligeronecesitamostrarseenlapantalla. El mtodo fillOval de Graphics dibuja un valo relleno. Los cuatro parmetros del mtodo representan el cuadro delimitadorenelcualsemuestraelvalo.Losprimerosdosparmetrossonlacoordenadaxsuperiorizquierdayla coordenada y superior izquierda del rea rectangular. Las ltimas dos coordenadas representan la anchura y la alturadelrearectangular.

//Fig.11.34:Pintor.javaPruebadePanelDibujo. importjava.awt.BorderLayout; importjavax.swing.JFrame; importjavax.swing.JLabel; publicclassPintor{ publicstaticvoidmain(Stringargs[]){ //creaobjetoJFrame JFrameaplicacion=newJFrame("Unprogramasimplededibujo"); PanelDibujopanelDibujo=newPanelDibujo();//creapaneldedibujo aplicacion.add(panelDibujo,BorderLayout.CENTER);//enelcentro //creaunaetiquetaylacolocaenlareginSOUTHdeBorderLayout aplicacion.add(newJLabel("Arrastreelratonparadibujar"), BorderLayout.SOUTH);

aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); aplicacion.setSize(400,200);//estableceeltamaodelmarco aplicacion.setVisible(true);//muestraelmarco

}//findemain }//findelaclasePintor

//Fig.11.35:Pintor.javaPruebadePanelDibujo. importjava.awt.BorderLayout; importjavax.swing.JFrame; importjavax.swing.JLabel; publicclassPintor{ publicstaticvoidmain(Stringargs[]){ //creaobjetoJFrame JFrameaplicacion=newJFrame("Unprogramasimplededibujo");

PanelDibujopanelDibujo=newPanelDibujo();//creapaneldedibujo aplicacion.add(panelDibujo,BorderLayout.CENTER);//enelcentro

//creaunaetiquetaylacolocaenlareginSOUTHdeBorderLayout aplicacion.add(newJLabel("Arrastreelratonparadibujar"),BorderLayout.SOUTH);

aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); aplicacion.setSize(400,200);//estableceeltamaodelmarco aplicacion.setVisible(true);//muestraelmarco

}//findemain }//findelaclasePintor

11.16Manejodeeventosdeteclas
LainterfazKeyListenerseutilizaparamanejareventosdeteclas,quesegenerancuandoseoprimenysueltanlasteclasen elteclado.ElmtodoaddKeyListenerdelaclaseComponentregistraunobjetoKeyListenerparauncomponente. ElmtodogetKeyCodedeKeyEventobtieneelcdigodeteclavirtualdelateclaoprimida.LaclaseKeyEventmantieneun conjuntodeconstantesdecdigodeteclavirtualquerepresentaatodaslasteclasenelteclado. ElmtodogetKeyTextdeKeyEventdevuelveunacadenaquecontieneelnombredelateclaqueseoprimi. ElmtodogetKeyChardeKeyEventobtieneelvalorUnicodedelcarcterescrito. ElmtodoisActionKeydeKeyEventdeterminasilateclaenuneventofueunatecladeaccin. El mtodo getModifiers de InputEvent determina si se oprimi alguna tecla modificadora (como Mays, Alt y Ctrl ) cuandoocurrieleventodetecla. El mtodo getKeyModifiersText de KeyEvent produce una cadena que contiene los nombres de las teclas modificadoras queseoprimieron.

//Fig.11.36:MarcoDemoTeclas.javaDemostracindeloseventosdepulsacindeteclas.
importjava.awt.Color; importjava.awt.event.KeyListener; importjava.awt.event.KeyEvent; importjavax.swing.JFrame; importjavax.swing.JTextArea;

publicclassMarcoDemoTeclasextendsJFrameimplementsKeyListener{ privateStringlinea1="";//primeralneadelreadetexto privateStringlinea2="";//segundalneadelreadetexto privateStringlinea3="";//terceralneadelreadetexto privateJTextAreaareaTexto;//readetextoparamostrarlasalida

publicMarcoDemoTeclas(){//constructordeMarcoDemoTeclas super("Demostracindeloseventosdepulsaciondeteclas");

areaTexto=newJTextArea(10,15);//estableceelobjetoJTextArea areaTexto.setText("Oprimacualquierteclaenelteclado..."); areaTexto.setEnabled(false);//deshabilitaelreadetexto areaTexto.setDisabledTextColor(Color.BLACK);//estableceelcolordeltexto add(areaTexto);//agregaareaTextoaJFrame

addKeyListener(this);//permitealmarcoprocesarloseventosdeteclas }//findelconstructordeMarcoDemoTeclas

publicvoidkeyPressed(KeyEventevento){//manejaeleventodeoprimircualquiertecla linea1=String.format("Teclaoprimida:%s",evento.getKeyText(evento.getKeyCode()));//imprimelateclaoprimida establecerLineas2y3(evento);//establecelaslneasdesalidadosytres }//findelmtodokeyPressed

publicvoidkeyReleased(KeyEventevento){//manejaeleventodeliberarcualquiertecla linea1=String.format("Teclaliberada:%s",evento.getKeyText(evento.getKeyCode()));//imprimelateclaliberada establecerLineas2y3(evento);//establecelaslneasdesalidadosytres }//findelmtodokeyReleased publicvoidkeyTyped(KeyEventevento){//manejaeleventodeoprimirunatecladeaccin linea1=String.format("Teclaoprimida:%s",evento.getKeyChar()); establecerLineas2y3(evento);//establecelaslneasdesalidadosytres }//findelmtodokeyTyped

privatevoidestablecerLineas2y3(KeyEventevento){//establecelaslneasdesalidadosytres linea2=String.format("Estatecla%sesunatecladeaccion",(evento.isActionKey()?"":"no"));

Stringtemp=evento.getKeyModifiersText(evento.getModifiers());

linea3=String.format("Teclasmodificadorasoprimidas:%s",(temp.equals("")?"ninguna":temp));//imprimemodificadoras

areaTexto.setText(String.format("%s\n%s\n%s\n",linea1,linea2,linea3));//imprimetreslneasdetexto

}//findelmtodoestablecerLineas2y3 }//findelaclaseMarcoDemoTeclas

//Fig.11.37:DemoTeclas.javaPruebadeMarcoDemoTeclas. importjavax.swing.JFrame; publicclassDemoTeclas{ publicstaticvoidmain(Stringargs[]){ MarcoDemoTeclasmarcoDemoTeclas=newMarcoDemoTeclas(); marcoDemoTeclas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoDemoTeclas.setSize(350,100);//estableceeltamaodelmarco marcoDemoTeclas.setVisible(true);//muestraelmarco

}//findemain }//findelaclaseDemoTeclas

11.17Administradoresdeesquemas
Los administradores de esquemas ordenan los componentes de la GUI en un contenedor, para fines de presentacin. TodoslosadministradoresdeesquemasimplementanlainterfazLayoutManager(paquetejava.awt). ElmtodosetLayoutdelaclaseContainerespecificaelesquemadeuncontenedor. FlowLayouteseladministradordeesquemasmssimple.LoscomponentesdelaGUIsecolocanenuncontenedor, deizquierdaaderecha,enelordenenelqueseagregaronalcontenedor.Cuandosellegaalbordedelcontenedor, los componentes siguen mostrndose en la siguiente lnea. La clase FlowLayout permite a los componentes de la GUIalinearsealaizquierda,alcentro(elvalorpredeterminado)yaladerecha. ElmtodosetAlignmentdeFlowLayoutcambialaalineacinparaunobjetoFlowLayout. El administrador de esquemas BorderLayout (el predeterminado para un objeto JFrame) ordena los componentes encincoregiones:NORTH,SOUTH,EAST,WESTyCENTER.NORTHcorrespondealapartesuperiordelcontenedor. Un BorderLayout limita a un objeto Container para que contenga cuando mucho cinco componentes; uno en cada regin. El administrador de esquemas GridLayoutdivide el contenedor en una cuadrcula,demanera que los componentes puedancolocarseenfilasycolumnas. El mtodo validate de Container recalcula el esquema del contenedor, con base en el administrador de esquemas actualparaeseobjetoContaineryelconjuntoactualdecomponentesdelaGUIquesemuestranenpantalla.


11.17.1FlowLayout
//Fig.11.39:MarcoFlowLayout.javaDemostracindelasalineacionesdeFlowLayout. importjava.awt.FlowLayout; importjava.awt.Container; importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.JFrame; importjavax.swing.JButton; publicclassMarcoFlowLayoutextendsJFrame{ privateJButtonbotonJButtonIzquierda;//botnparaestablecerlaalineacinalaizquierda privateJButtonbotonJButtonCentro;//botnparaestablecerlaalineacinalcentro privateJButtonbotonJButtonDerecha;//botnparaestablecerlaalineacinaladerecha privateFlowLayoutesquema;//objetoesquema privateContainercontenedor;//contenedorparaestablecerelesquema //establecelaGUIyregistraloscomponentesdeescuchadebotones publicMarcoFlowLayout(){ super("DemostraciondeFlowLayout"); esquema=newFlowLayout();//creaobjetoFlowLayout contenedor=getContentPane();//obtienecontenedorparaesquema setLayout(esquema);//estableceelesquemadelmarco //establecebotonJButtonIzquierdayregistracomponentedeescucha botonJButtonIzquierda=newJButton("Izquierda");//creabotnIzquierda add(botonJButtonIzquierda);//agregabotnIzquierdaalmarco botonJButtonIzquierda.addActionListener( newActionListener()//claseinternaannima { //procesaeventodebotonJButtonIzquierda publicvoidactionPerformed(ActionEventevento) { esquema.setAlignment(FlowLayout.LEFT); //realinealoscomponentesadjuntos esquema.layoutContainer(contenedor); }//findelmtodoactionPerformed }//findelaclaseinternaannima );//findelallamadaaaddActionListener

Figura 11.39 | FlowLayout permite a los componentes fluir a travs de varias lneas. (Parte 1 de 2).

//Fig.11.40:DemoFlowLayout.javaPruebaMarcoFlowLayout. importjavax.swing.JFrame; publicclassDemoFlowLayout{ publicstaticvoidmain(Stringargs[]){ MarcoFlowLayoutmarcoFlowLayout=newMarcoFlowLayout(); marcoFlowLayout.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoFlowLayout.setSize(350,75);//estableceeltamaodelmarco marcoFlowLayout.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDemoFlowLayout

11.17.2BorderLayout //Fig.11.41:MarcoBorderLayout.javaDemostracindeBorderLayout. importjava.awt.BorderLayout; importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.JFrame; importjavax.swing.JButton; publicclassMarcoBorderLayoutextendsJFrameimplementsActionListener{ privateJButtonbotones[];//arreglodebotonesparaocultarporciones privatefinalStringnombres[]={"OcultarNorte","OcultarSur","OcultarEste","OcultarOeste","OcultarCentro"}; privateBorderLayoutesquema;//objetoBorderLayout //establecelaGUIyelmanejodeeventos publicMarcoBorderLayout(){ super("DemostraciondeBorderLayout"); esquema=newBorderLayout(5,5);//espaciosde5pxeles setLayout(esquema);//estableceelesquemadelmarco botones=newJButton[nombres.length];//estableceeltamaodelarreglo //creaobjetosJButtonyregistracomponentesdeescuchaparaellos for(intcuenta=0;cuenta<nombres.length;cuenta++){ botones[cuenta]=newJButton(nombres[cuenta]); botones[cuenta].addActionListener(this); }//findefor Figura 11.41 | BorderLayout que contiene cinco botones (Parte 1 de 2).

Figura 11.41 | BorderLayout que contiene cinco botones (Parte 2 de 2). //Fig.11.42:DemoBorderLayout.javaPruebadeMarcoBorderLayout. importjavax.swing.JFrame; publicclassDemoBorderLayout{ publicstaticvoidmain(Stringargs[]){ MarcoBorderLayoutmarcoBorderLayout=newMarcoBorderLayout(); marcoBorderLayout.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoBorderLayout.setSize(375,200);//estableceeltamaodelmarco marcoBorderLayout.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDemoBorderLayout

add(botones[0],BorderLayout.NORTH);//agregabotnalnorte add(botones[1],BorderLayout.SOUTH);//agregabotnalsur add(botones[2],BorderLayout.EAST);//agregabotnaleste add(botones[3],BorderLayout.WEST);//agregabotnaloeste add(botones[4],BorderLayout.CENTER);//agregabotnalcentro }//findelconstructordeMarcoBorderLayout //manejaloseventosdebotn publicvoidactionPerformed(ActionEventevento){ //compruebaelorigendeleventoydistribuyeelpaneldecontenidodemaneraacorde for(JButtonboton:botones){ if(evento.getSource()==boton) boton.setVisible(false);//ocultaelbotnoprimido else boton.setVisible(true);//muestralosdemsbotones }//findefor esquema.layoutContainer(getContentPane());//distribuyeelpaneldecontenido }//findelmtodoactionPerformed }//findelaclaseMarcoBorderLayout

11.17.3GridLayout //Fig.11.43:MarcoGridLayout.javaDemostracindeGridLayout. importjava.awt.GridLayout; importjava.awt.Container; importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.JFrame; importjavax.swing.JButton; publicclassMarcoGridLayoutextendsJFrameimplementsActionListener{ privateJButtonbotones[];//arreglodebotones privatefinalStringnombres[]={"uno","dos","tres","cuatro","cinco","seis"}; privatebooleanalternar=true;//alternaentredosesquemas privateContainercontenedor;//contenedordelmarco privateGridLayoutcuadricula1;//primerobjetoGridLayout privateGridLayoutcuadricula2;//segundoobjetoGridLayout //constructorsinargumentos publicMarcoGridLayout(){ super("DemostraciondeGridLayout"); cuadricula1=newGridLayout(2,3,5,5);//2por3;espaciosde5 cuadricula2=newGridLayout(3,2);//3por2;sinespacios contenedor=getContentPane();//obtieneelpaneldecontenido setLayout(cuadricula1);//estableceesquemadeobjetoJFrame botones=newJButton[nombres.length];//creaarreglodeobjetosJButton for(intcuenta=0;cuenta<nombres.length;cuenta++){ botones[cuenta]=newJButton(nombres[cuenta]); botones[cuenta].addActionListener(this);//registracomponentedeescucha add(botones[cuenta]);//agregabotonaobjetoJFrame }//findefor }//findelconstructordeMarcoGridLayout //manejaeventosdeboton,alternandoentrelosesquemas publicvoidactionPerformed(ActionEventevento){ if(alternar) contenedor.setLayout(cuadricula2);//estableceesquemaalprimero else contenedor.setLayout(cuadricula1);//estableceesquemaalsegundo alternar=!alternar;//establecealternarasuvaloropuesto contenedor.validate();//redistribuyeelcontenedor }//findelmtodoactionPerformed }//findelaclaseMarcoGridLayout

//Fig.11.44:DemoGridLayout.javaPruebadeMarcoGridLayout. importjavax.swing.JFrame;

publicclassDemoGridLayout{ publicstaticvoidmain(Stringargs[]){ MarcoGridLayoutmarcoGridLayout=newMarcoGridLayout(); marcoGridLayout.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoGridLayout.setSize(300,200);//estableceeltamaodelmarco marcoGridLayout.setVisible(true);//muestraelmarco

}//findemain }//findelaclaseDemoGridLayout

11.18Usodepanelesparaadministraresquemasmscomplejos

LasGUIscomplejas(comoladelafigura11.1)requierenquecadacomponentesecoloqueenunaubicacinexacta.A menudoconsistendevariospaneles,endondeloscomponentesdecadapanelseordenanenunesquemaespecfico.La claseJPanelextiendeaJComponent,yJComponentextiendealaclaseContainer,porloquetodoJPanelesunContainer. Porlotanto,todoobjetoJPanelpuedetenercomponentes,incluyendootrospaneles,loscualesseadjuntanmedianteel mtodoadddeContainer.Laaplicacindelasfiguras11.45y11.46demuestracmopuedeusarseunobjetoJPanelpara crearunesquemamscomplejo,enelcualsecoloquenvariosobjetosJButtonenlareginSOUTHdeunesquema BorderLayout. UnavezdeclaradoelobjetoJPanelllamadopanelBotonesenlalnea11,ycreadoenlalnea19,enlalnea 20seestableceelesquemadepanelBotonesenGridLayoutconunafilaycincocolumnas(haycincoobjetos JButtonenelarreglobotones).Enlaslneas23a27seagreganloscincoobjetosJButtondelarreglobotonesalobjeto JPanelenelciclo.Enlalnea26seagreganlosbotonesdirectamentealobjetoJPanel(laclaseJPanelnotieneunpanelde contenido,adiferenciadeJFrame).Enlalnea29seutilizaelobjetoBorderLayoutpredeterminadoparaagregar panelBotonesalareginSOUTH.ObservequeestaregintienelamismaalturaquelosbotonesenpanelBotones.Un objetoJPanelajustasutamaodeacuerdoconloscomponentesquecontiene. Amedidaqueseagreganmscomponentes,elobjetoJPanelcrece(deacuerdoconlasrestriccionesdesuadministrador deesquemas)paradarcabidaaesosnuevoscomponentes.Ajusteeltamaodelaventanaparaqueveacmoel administradordeesquemasafectaaltamaodelosobjetosJButton.

//Fig.11.43:MarcoPanel.javaUsodeunobjetoJPanelparaayudaradistribuirloscomponentes. importjava.awt.GridLayout; importjava.awt.BorderLayout; importjavax.swing.JFrame; importjavax.swing.JPanel; importjavax.swing.JButton; publicclassMarcoPanelextendsJFrame{ privateJPanelpanelBotones;//panelquecontienelosbotones privateJButtonbotones[];//arreglodebotones //constructorsinargumentos publicMarcoPanel(){ super("DemostraciondePanel"); botones=newJButton[5];//creaelarreglobotones panelBotones=newJPanel();//estableceelpanel panelBotones.setLayout(newGridLayout(1,botones.length)); //creayagregalosbotones for(intcuenta=0;cuenta<botones.length;cuenta++){ botones[cuenta]=newJButton("Boton"+(cuenta+1)); panelBotones.add(botones[cuenta]);//agregaelbotnalpanel }//findefor add(panelBotones,BorderLayout.SOUTH);//agregaelpanelaJFrame }//findelconstructordeMarcoPanel }//findelaclaseMarcoPanel

//Fig.11.44:DemoPanel.javaPruebadeMarcoPanel. importjavax.swing.JFrame; publicclassDemoPanelextendsJFrame{ publicstaticvoidmain(Stringargs[]){ MarcoPanelmarcoPanel=newMarcoPanel(); marcoPanel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoPanel.setSize(450,200);//estableceeltamaodelmarco marcoPanel.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDemoPanel

11.19JTextArea

Un objeto JTextArea proporciona un rea para manipular varias lneas de texto. JTextArea es una subclase de JTextComponent, la cual declara mtodos comunes para objetos JTextField, JTextArea y varios otros componentes deGUIbasadosentexto.

La clase Box es una subclase de Container que utiliza un administrador de esquemas BoxLayout para ordenar los componentesdelaGUI,yaseaenformahorizontalovertical. El mtodo static createHorizontalBox de Box crea un objeto Box que ordena los componentes de izquierda a derecha,enelordenenelqueseadjuntan. El mtodo getSelectedText (que hereda JTextArea de JTextComponent) devuelve el texto seleccionado de un objetoJTextArea. Podemos establecer las polticas de las barras de desplazamiento horizontal y vertical de un objeto JScrollPane al momentodecrearlo.LosmtodossetHorizontalScrollBarPolicyysetVerticalScrollBarPolicydeJScrollPanepueden usarseparamodificarlaspolticasdelasbarrasdedesplazamientoencualquiermomento.

//Fig.11.47:MarcoAreaTexto.java //Copiaeltextoseleccionadodeunreadetextoaotra. importjava.awt.event.ActionListener; importjava.awt.event.ActionEvent; importjavax.swing.Box; importjavax.swing.JFrame; importjavax.swing.JTextArea; importjavax.swing.JButton; importjavax.swing.JScrollPane; publicclassMarcoAreaTextoextendsJFrame{ privateJTextAreaareaTexto1;//muestracadenadedemostracin privateJTextAreaareaTexto2;//eltextoresaltadosecopiaaqu privateJButtonbotonCopiar;//iniciaelcopiadodetexto //constructorsinargumentos publicMarcoAreaTexto() { super("DemostraciondeJTextArea"); Boxcuadro=Box.createHorizontalBox();//creauncuadro Stringdemo="Estaesunacadenade\ndemostracionpara\n"+ "ilustrarcomocopiartexto\ndeunareadetextoa\n"+ "otra,usandoun\neventoexterno\n"; areaTexto1=newJTextArea(demo,10,15);//creareadetexto1 cuadro.add(newJScrollPane(areaTexto1));//agregapaneldedesplazamiento botonCopiar=newJButton("Copiar>>>");//creabotnparacopiar cuadro.add(botonCopiar);//agregabotndecopiaalcuadro botonCopiar.addActionListener( newActionListener()//claseinternaannima { //estableceeltextoenareaTexto2coneltextoseleccionadodeareaTexto1 publicvoidactionPerformed(ActionEventevento) { areaTexto2.setText(areaTexto1.getSelectedText()); }//findelmtodoactionPerformed }//findelaclaseinternaannima );//findelallamadaaaddActionListener areaTexto2=newJTextArea(10,15);//creasegundareadetexto areaTexto2.setEditable(false);//deshabilitaedicin cuadro.add(newJScrollPane(areaTexto2));//agregapaneldedesplazamiento add(cuadro);//agregacuadroalmarco }//findelconstructordeMarcoAreaTexto }//findelaclaseMarcoAreaTexto

//Fig.11.48:DemoAreaTexto.java //Copiaeltextoseleccionadodeunreadetextoaotra. importjavax.swing.JFrame; publicclassDemoAreaTexto{ publicstaticvoidmain(Stringargs[]){ MarcoAreaTextomarcoAreaTexto=newMarcoAreaTexto(); marcoAreaTexto.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); marcoAreaTexto.setSize(425,200);//estableceeltamaodelmarco marcoAreaTexto.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDemoAreaTexto

Unidad12.GrficosyJava2D

12.1Introduccin

ElsistemadecoordenadasdeJavaesunesquemaparaidentificartodoslosposiblespuntosenlapantalla. Un par de coordenadas est compuesto de una coordenada x (la coordenada horizontal) y una coordenada y (la coordenadavertical). Para mostrar texto y figuras en la pantalla, se especifican sus coordenadas. Estas coordenadas se utilizan para indicarendndedebenmostrarselosgrficosenunapantalla. Las unidades de las coordenadas se miden en pxeles. Un pxel es la unidad ms pequea de resolucin de un monitordecomputadora.

12.2Contextosyobjetosdegrficos
UncontextodegrficosenJavapermitedibujarenlapantalla. La clase Graphics contiene mtodos para dibujar cadenas, lneas, rectngulos y otras figuras. Tambin se incluyen mtodosparamanipulartiposdeletraycolores. UnobjetoGraphicsadministrauncontextodegrficosydibujapxelesenlapantalla,loscualesrepresentanaotros objetosgrficos(porejemplo,lneas,elipses,rectngulosyotrospolgonos. LaclaseGraphicsesunaclaseabstract.EstocontribuyealaportabilidaddeJava;cuandoseimplementaJavaenuna plataforma, se crea una subclase de Graphics, la cual implementa las herramientas de dibujo. Esta implementacin seocultadenosotrosmediantelaclaseGraphics,lacualproporcionalainterfazquenospermiteutilizarlosgrficos enformaindependientedelaplataforma. La clase JComponent contiene un mtodo paintComponent que puede usarse para dibujar los grficos en un componentedeSwing. El mtodo paintComponent recibe como argumento un objeto Graphics que el sistema pasa al mtodo paintComponentcuandouncomponenteligerodeSwingnecesitavolverapintarse. Pocas veces es necesario que el programador llame al mtodo paintComponent directamente, ya que el dibujo de grficos es un proceso controlado por eventos. Cuando se ejecuta una aplicacin, el contenedor de sta llama al mtodopaintComponent.ParaquepaintComponentsellameotravez,debeocurrirunevento. CuandosemuestraunobjetoJComponent,sehaceunallamadaasumtodopaintComponent. LosprogramadoresllamanalmtodorepaintparaactualizarlosgrficosquesedibujanenelcomponentedeSwing.

12.3 Control de colores


LaclaseColordeclaramtodosyconstantesparamanipularloscoloresenunprograma. Todocolorsecreaapartirdeuncomponenterojo,unoverdeyunoazul.Enconjuntoestoscomponentessellaman valoresRGB. LoscomponentesRGBespecificanlacantidadderojo,verdeyazulenuncolorrespectivamente.Entremayorseael valorRGB,mayorserlacantidaddeesecolorespecfico. Los mtodos getRed, getGreen y getBlue de Color devuelven valores enteros de 0 a 255, los cuales representan la cantidadderojo,verdeyazul,respectivamente. ElmtodogetColordeGraphicsdevuelveunobjetoColorquerepresentaelcoloractualparadibujar. ElmtodosetColordegraphicsestableceelcoloractualparadibujar.

El mtodo fillRect de Graphics dibuja un rectngulo rellenoporelcoloractualdelobjetoGraphics. El mtodo drawString de Graphics dibuja un objeto Stringenelcoloractual. El componente de GUI JColorChooser permite a los usuariosdeunaaplicacinseleccionarcolores. La clase JColorChooser proporciona el mtodo de conveniencia static llamado showDialog, que crea un objeto JColorChooser, lo adjunta a un cuadro de dilogoymuestraesecuadrodedilogo. Mientras el cuadro de dilogo de seleccin de color est en la pantalla, el usuario no podr interactuar con el componente padre. A este tipo de cuadro de dilogoselellamacuadrodedilogomodal.

//Fig.12.5:JPanelColor.javaDemostracindeobjetosColor. importjava.awt.Graphics; importjava.awt.Color; importjavax.swing.JPanel;

publicclassJPanelColorextendsJPanel{ //dibujarectngulosyobjetosStringendistintoscolores publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaelmtodopaintComponentdelasuperclase

this.setBackground(Color.WHITE);

//establecenuevocolordedibujo,usandovaloresenteros g.setColor(newColor(255,0,0)); g.fillRect(15,25,100,20); g.drawString("RGBactual:"+g.getColor(),130,40);

//establecenuevocolordedibujo,usandovaloresdepuntoflotante g.setColor(newColor(0.50f,0.75f,0.0f)); g.fillRect(15,50,100,20); g.drawString("RGBactual:"+g.getColor(),130,65);

//establecenuevocolordedibujo,usandoobjetosColorstatic g.setColor(Color.BLUE); g.fillRect(15,75,100,20); g.drawString("RGBactual:"+g.getColor(),130,90);

//muestralosvaloresRGBindividuales Colorcolor=Color.MAGENTA; g.setColor(color); g.fillRect(15,100,100,20); g.drawString("ValoresRGB:"+color.getRed()+","+ color.getGreen()+","+color.getBlue(),130,115);

}//findelmtodopaintComponent }//findelaclaseJPanelColor //Fig.12.6:MostrarColores.javaDemostracindeobjetosColor. importjavax.swing.JFrame;

publicclassMostrarColores{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaobjetoJPanelColor JFrameframe=newJFrame("Usodecolores"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanelColorjPanelColor=newJPanelColor();//createJPanelColor frame.add(jPanelColor);//agregajPanelColoramarco frame.setSize(400,180);//estableceeltamaodelmarco frame.setVisible(true);//muestraelmarco }//findemain }//findelaclaseMostrarColores

//Fig.12.7:MostrarColores2JFrame.javaSeleccindecoloresconJColorChooser. importjava.awt.BorderLayout; importjava.awt.Color; importjava.awt.event.ActionEvent; importjava.awt.event.ActionListener; importjavax.swing.JButton; importjavax.swing.JFrame; importjavax.swing.JColorChooser; importjavax.swing.JPanel;

publicclassMostrarColores2JFrameextendsJFrame{ privateJButtoncambiarColorJButton; privateColorcolor=Color.LIGHT_GRAY; privateJPanelcoloresJPanel;

//establecelaGUI publicMostrarColores2JFrame(){ super("UsodeJColorChooser");

//creaobjetoJPanelparamostrarcolor coloresJPanel=newJPanel(); coloresJPanel.setBackground(color);

//establececambiarColorJButtonyregistrasumanejadordeeventos cambiarColorJButton=newJButton("Cambiarcolor"); cambiarColorJButton.addActionListener(

newActionListener()//claseinternaannima { //muestraJColorChoosercuandoelusuariohaceclicconelbotn publicvoidactionPerformed(ActionEventevento){ color=JColorChooser.showDialog( MostrarColores2JFrame.this,"Seleccioneuncolor",color);

//estableceelcolorpredeterminado,sinosedevuelveuncolor if(color==null)color=Color.LIGHT_GRAY;

//cambiaelcolordefondodelpaneldecontenido coloresJPanel.setBackground(color);

}//findelmtodoactionPerformed }//findelaclaseinternaannima );//findelallamadaaaddActionListener add(coloresJPanel,BorderLayout.CENTER);//agregacoloresJPanel add(cambiarColorJButton,BorderLayout.SOUTH);//agregabotn

setSize(400,130);//estableceeltamaodelmarco setVisible(true);//muestraelmarco

}//findelconstructordeMostrarColores2JFrame }//findelaclaseMostrarColores2JFrame

//Fig.12.8:MostrarColores2.javaSeleccindecoloresconJColorChooser. importjavax.swing.JFrame; publicclassMostrarColores2{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ MostrarColores2JFrameaplicacion=newMostrarColores2JFrame(); aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}//findemain }//findelaclaseMostrarColores2

12.4Controldetiposdeletra

LaclaseFontcontienemtodosyconstantesparamanipulartiposdeletra. ElconstructordelaclaseFontrecibetresargumentos:elnombre,estiloytamaodeltipodeletra. El estilo de tipo de letra de un objeto Font puede ser Font.PLAIN, Font.ITALIC o Font.BOLD (cada uno es un campo static de la clase Font). Los estilos de tipos de letra pueden usarse combinados (por ejemplo, Font.ITALIC + Font.BOLD). Eltamaodeuntipodeletrasemideenpuntos.Unpuntoes1/72deunapulgada. ElmtodosetFontdeGraphicsestableceeltipodeletraparadibujareltextoquesevaamostrar. ElmtodogetStyledeFontdevuelveunvalorenteroquerepresentaelestiloactualdelobjetoFont. ElmtodogetSizedeFontdevuelveeltamaodeltipodeletra,enpuntos. ElmtodogetNamedeFontdevuelveelnombredeltipodeletraactual,comounacadena. El mtodo getFamily de Font devuelve el nombre de la familia a la que pertenece el tipo de letra actual. El nombre delafamiliadeltipodeletraesespecficodecadaplataforma. LaclaseFontMetricscontienemtodosparaobtenerinformacinsobrelostiposdeletra. Lamtricadetiposdeletraincluyelaaltura,eldescendente(ladistanciaentrelabasedelalneayelpuntoinferior del tipo de letra), el ascendente (la cantidad que se eleva un carcter por encima de la base de la lnea) y el interlineado (la diferencia entre el descendente de una lnea de texto y el ascendente de la lnea de texto que est arriba;esdecir,elespaciamientoentrelneas).

Figura 12.9 | Las fi chas HSB y RGB del cuadro de dilogo JColorChooser.

//Fig.12.11:FontJPanel.javaMuestracadenasendistintostiposdeletraycolores.

importjava.awt.Font; importjava.awt.Color; importjava.awt.Graphics; importjavax.swing.JPanel; publicclassFontJPanelextendsJPanel{ //muestraobjetosStringendistintostiposdeletraycolores publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaalmtodopaintComponentdelasuperclase //estableceeltipodeletraaSerif(Times),negrita,12puntosydibujaunacadena g.setFont(newFont("Serif",Font.BOLD,12)); g.drawString("Serif12puntos,negrita.",20,50); //estableceeltipodeletraaMonospaced(Courier),cursiva,24puntosydibujaunacadena g.setFont(newFont("Monospaced",Font.ITALIC,24)); g.drawString("Monospaced24puntos,cursiva.",20,70); //estableceeltipodeletraaSansSerif(Helvetica),simple,14puntosydibujaunacadena g.setFont(newFont("SansSerif",Font.PLAIN,14)); g.drawString("SansSerif14puntos,simple.",20,90); //estableceeltipodeletraaSerif(Times),negrita/cursiva,18puntosydibujaunacadena g.setColor(Color.RED); g.setFont(newFont("Serif",Font.BOLD+Font.ITALIC,18)); g.drawString(g.getFont().getName()+""+g.getFont().getSize()+ "puntos,negritacursiva.",20,110);

}//findelmtodopaintComponent }//findelaclaseFontJPanel

//Fig.12.12:TiposDeLetra.javaUsodetiposdeletra. importjavax.swing.JFrame;

publicclassTiposDeLetra{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaFontJPanel JFramemarco=newJFrame("Usodetiposdeletra"); marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

FontJPanelfontJPanel=newFontJPanel();//creaobjetoFontJPanel marco.add(fontJPanel);//agregaobjetofontJPanelalmarco marco.setSize(475,170);//estableceeltamaodelmarco marco.setVisible(true);//muestraelmarco

}//findelaclaseTiposDeLetra

}//findemain

Mtrica de los tipos de letra.

//Fig.12.15:MetricaJPanel.javaMtodosdeFontMetricsyGraphicstilesparaobtenerlamtricadelostiposdeletra. importjava.awt.Font; importjava.awt.FontMetrics; importjava.awt.Graphics; importjavax.swing.JPanel;

publicclassMetricaJPanelextendsJPanel{ //muestralamtricadelostiposdeletra publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaalmtodopaintComponentdelasuperclase

g.setFont(newFont("SansSerif",Font.BOLD,12)); FontMetricsmetrica=g.getFontMetrics(); g.drawString("Tipodeletraactual:"+g.getFont(),10,40); g.drawString("Ascendente:"+metrica.getAscent(),10,55); g.drawString("Descendente:"+metrica.getDescent(),10,70); g.drawString("Altura:"+metrica.getHeight(),10,85); g.drawString("Interlineado:"+metrica.getLeading(),10,100);

FonttipoLetra=newFont("Serif",Font.ITALIC,14); metrica=g.getFontMetrics(tipoLetra); g.setFont(tipoLetra); g.drawString("Tipodeletraactual:"+tipoLetra,10,130); g.drawString("Ascendente:"+metrica.getAscent(),10,145); g.drawString("Descendente:"+metrica.getDescent(),10,160); g.drawString("Altura:"+metrica.getHeight(),10,175); g.drawString("Interlineado:"+metrica.getLeading(),10,190);

}//findelmtodopaintComponent }//findelaclaseMetricaJPanel //Fig.12.16:Metrica.javaMuestralamtricadelostiposdeletra. importjavax.swing.JFrame;

publicclassMetrica{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaobjetoMetricaJPanel JFramemarco=newJFrame("DemostraciondeFontMetrics"); marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

MetricaJPanelmetricaJPanel=newMetricaJPanel(); marco.add(metricaJPanel);//agregametricaJPanelalmarco marco.setSize(530,250);//estableceeltamaodelmarco marco.setVisible(true);//muestraelmarco }//findemain }//findelaclaseMetrica

12.5Dibujodelneas,rectngulosyvalos
LosmtodosfillRoundRectydrawRoundRectdeGraphicsdibujanrectngulosconesquinasredondeadas. Losmtodosdraw3DRectyfill3DRectdeGraphicsdibujanrectngulostridimensionales. LosmtodosdrawOvalyfillOvaldeGraphicsdibujanvalos.

//Fig.12.18:LineasRectsOvalosJPanel.javaDibujodelneas,rectngulosyvalos. importjava.awt.Color; importjava.awt.Graphics; importjavax.swing.JPanel;

publicclassLineasRectsOvalosJPanelextendsJPanel{ //muestravariaslneas,rectngulosyvalos publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaalmtodopaintComponentdelasuperclase

this.setBackground(Color.WHITE);

g.setColor(Color.RED); g.drawLine(5,30,380,30);

g.setColor(Color.BLUE); g.drawRect(5,40,90,55); g.fillRect(100,40,90,55);

g.setColor(Color.BLACK); g.fillRoundRect(195,40,90,55,50,50); g.drawRoundRect(290,40,90,55,20,20);

g.setColor(Color.YELLOW); g.draw3DRect(5,100,90,55,true); g.fill3DRect(100,100,90,55,false);

g.setColor(Color.MAGENTA); g.drawOval(195,100,90,55); g.fillOval(290,100,90,55);

}//findelmtodopaintComponent }//findelaclaseLineasRectsOvalosJPanel //Fig.12.19:LineasRectsOvalos.javaDibujodelneas,rectngulosyvalos. importjava.awt.Color; importjavax.swing.JFrame;

publicclassLineasRectsOvalos{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaLineasRectsOvalosJPanel JFramemarco=newJFrame("Dibujodelineas,rectangulosyovalos"); marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); LineasRectsOvalosJPanellineasRectsOvalosJPanel=newLineasRectsOvalosJPanel(); lineasRectsOvalosJPanel.setBackground(Color.WHITE); marco.add(lineasRectsOvalosJPanel);//agregaelpanelalmarco marco.setSize(400,210);//estableceeltamaodelmarco marco.setVisible(true);//muestraelmarco

}//findemain }//findelaclaseLineasRectsOvalos

Unarcosedibujacomounaporcindeunvalo. Losarcosseextiendendesdeunnguloinicial,segnelnmerodegradosespecificadosporelngulodelarco. LosmtodosdrawArcyfillArcdeGraphicsseutilizanparadibujararcos.

12.6Dibujodearcos

//Fig.12.24:ArcosJPanel.java //Dibujodearcos. importjava.awt.Color; importjava.awt.Graphics; importjavax.swing.JPanel; publicclassArcosJPanelextendsJPanel{ //dibujarectngulosyarcos publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaalmtodopaintComponentdelasuperclase //empiezaen0yseextiendehasta360grados g.setColor(Color.RED); g.drawRect(15,35,80,80); g.setColor(Color.BLACK); g.drawArc(15,35,80,80,0,360); //empiezaen0yseextiendehasta110 g.setColor(Color.RED); g.drawRect(100,35,80,80); g.setColor(Color.BLACK); g.drawArc(100,35,80,80,0,110); //empiezaen0yseextiendehasta270grados g.setColor(Color.RED); g.drawRect(185,35,80,80); g.setColor(Color.BLACK); g.drawArc(185,35,80,80,0,270); //empiezaen0yseextiendehasta360grados g.fillArc(15,120,80,40,0,360); //empiezaen270yseextiendehasta90grados g.fillArc(100,120,80,40,270,90); //empiezaen0yseextiendehasta270grados g.fillArc(185,120,80,40,0,270); }//findelmtodopaintComponent }//findelaclaseArcosJPanel

//Fig.12.25:DibujarArcos.java //Dibujodearcos. importjavax.swing.JFrame; publicclassDibujarArcos{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaArcosJPanel JFramemarco=newJFrame("Dibujodearcos"); marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ArcosJPanelarcosJPanel=newArcosJPanel();//creaobjetoArcosJPanel marco.add(arcosJPanel);//agregaarcosJPanelalmarco marco.setSize(300,210);//estableceeltamaodelmarco marco.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDibujarArcos

12.7Dibujodepolgonosypolilneas
LaclasePolygoncontienemtodosparacrearpolgonos. Lospolgonossonfigurasconvarioslados,compuestasdesegmentosdelnearecta. Laspolilneassonunasecuenciadepuntosconectados. ElmtododrawPolylinedeGraphicsmuestraunaseriedelneasconectadas. LosmtodosdrawPolygonyfillPolygondeGraphicsseutilizanparadibujarpolgonos. ElmtodoaddPointdelaclasePolygonagregaparesdecoordenadasxyyaunobjetoPolygon.

//Fig.12.27:PoligonosJPanel.javaDibujodepolgonos. importjava.awt.Graphics; importjava.awt.Polygon; importjavax.swing.JPanel;

publicclassPoligonosJPanelextendsJPanel{ //dibujapolgonosypolilneas publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaalmtodopaintComponentdelasuperclase

//dibujapolgonoconobjetopolgono intvaloresX[]={20,40,50,30,20,15}; intvaloresY[]={50,50,60,80,80,60}; Polygonpoligono1=newPolygon(valoresX,valoresY,6); g.drawPolygon(poligono1);

//dibujapolilneascondosarreglos intvaloresX2[]={70,90,100,80,70,65,60}; intvaloresY2[]={100,100,110,110,130,110,90}; g.drawPolyline(valoresX2,valoresY2,7);

//rellenapolgonocondosarreglos intvaloresX3[]={120,140,150,190}; intvaloresY3[]={40,70,80,60}; g.fillPolygon(valoresX3,valoresY3,4);

//dibujapolgonorellenoconobjetoPolygon Polygonpoligono2=newPolygon(); poligono2.addPoint(165,135); poligono2.addPoint(175,150); poligono2.addPoint(270,200); poligono2.addPoint(200,220); poligono2.addPoint(130,180); g.fillPolygon(poligono2); }//findelmtodopaintComponent }//findelaclasePoligonosJPanel

//Fig.12.28:DibujarPoligonos.javaDibujodepolgonos. importjavax.swing.JFrame;

publicclassDibujarPoligonos{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaobjetoPoligonosJPanel JFramemarco=newJFrame("Dibujodepoligonos"); marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

PoligonosJPanelpoligonosJPanel=newPoligonosJPanel(); marco.add(poligonosJPanel);//agregapoligonosJPanelalmarco marco.setSize(280,270);//estableceeltamaodelmarco marco.setVisible(true);//muestraelmarco }//findemain }//findelaclaseDibujarPoligonos

12.8LaAPIJava2D

La API Java 2D proporciona herramientas de grficos bidimensionales avanzadas para los programadores que requierenmanipulacionesdegrficosdetalladosycomplejos. LaclaseGraphics2D,queextiendealaclaseGraphics,seutilizaparadibujarconlaAPIJava2D. LaAPIJava2Dcontienevariasclasesparadibujarfiguras,incluyendoLine2D.Double,Rectangle2D.Double, Rectangle2D.Double,Arc2D.DoubleyEllipse2D.Double. La clase GradientPaint ayuda a dibujar una figura en colores que cambian en forma gradual; a esto se le conoce comodegradado. ElmtodofilldeGraphics2DdibujaunobjetoShaperelleno;unobjetoqueimplementaalainterfazShape. LaclaseBasicStrokeayudaaespecificarlascaractersticasdedibujodelneas. ElmtododrawdeGraphics2DseutilizaparadibujarunobjetoShape. Las clases GradientPaint y TexturePaint ayudan a especificar las caractersticas para rellenar fi guras con colores o patrones. Unarutageneralesunafiguraconstruidaapartirdelneasrectasycurvascomplejas. UnarutageneralserepresentamedianteunobjetodelaclaseGeneralPath. ElmtodomoveTodeGeneralPathespecificaelprimerpuntoenunarutageneral. El mtodo lineTo de GeneralPath dibuja una lnea hasta el siguiente punto en la ruta. Cada nueva llamada a lineTo dibujaunalneadesdeelpuntoanteriorhastaelpuntoactual. ElmtodoclosePathdeGeneralPathdibujaunalneadesdeelltimopuntohastaelpuntoespecificadoenlaltima llamadaamoveTo.Estocompletalarutageneral. ElmtodotranslatedeGraphics2Dseutilizaparamoverelorigendedibujohastaunanuevaubicacin. ElmtodorotatedeGraphics2Dseutilizaparagirarlasiguientefiguraamostrar.

Figura 12.29 | Figuras de Java 2D. (Parte 1 de 2).

//Fig.12.29:FigurasJPanel.java //DemostracindealgunasfigurasdeJava2D. importjava.awt.Color; importjava.awt.Graphics; importjava.awt.BasicStroke; importjava.awt.GradientPaint; importjava.awt.TexturePaint; importjava.awt.Rectangle; importjava.awt.Graphics2D; importjava.awt.geom.Ellipse2D; importjava.awt.geom.Rectangle2D; importjava.awt.geom.RoundRectangle2D; importjava.awt.geom.Arc2D; importjava.awt.geom.Line2D; importjava.awt.image.BufferedImage; importjavax.swing.JPanel; publicclassFigurasJPanelextendsJPanel{ //dibujafigurasconlaAPIJava2D publicvoidpaintComponent(Graphicsg){ super.paintComponent(g);//llamaalmtodopaintComponentdelasuperclase Graphics2Dg2d=(Graphics2D)g;//convierteagenobjetoGraphics2D //dibujaunelipseen2D,rellenoconungradientecolorazulamarillo g2d.setPaint(newGradientPaint(5,30,Color.BLUE,35,100, Color.YELLOW,true)); g2d.fill(newEllipse2D.Double(5,30,65,100)); //dibujarectnguloen2Ddecolorrojo g2d.setPaint(Color.RED); g2d.setStroke(newBasicStroke(10.0f)); g2d.draw(newRectangle2D.Double(80,30,65,100));

//dibujarectngulodelimitadoren2D,conunfondoconbfer BufferedImageimagenBuf=newBufferedImage(10,10, BufferedImage.TYPE_INT_RGB);

//obtieneobjetoGraphics2DdeimagenBufydibujaenl Graphics2Dgg=imagenBuf.createGraphics(); gg.setColor(Color.YELLOW);//dibujaencoloramarillo gg.fillRect(0,0,10,10);//dibujaunrectngulorelleno gg.setColor(Color.BLACK);//dibujaencolornegro gg.drawRect(1,1,6,6);//dibujaunrectngulo gg.setColor(Color.BLUE);//dibujaencolorazul gg.fillRect(1,1,3,3);//dibujaunrectngulorelleno gg.setColor(Color.RED);//dibujaencolorrojo gg.fillRect(4,4,3,3);//dibujaunrectngulorelleno

//pintaaimagenBufenelobjetoJFrame g2d.setPaint(newTexturePaint(imagenBuf,newRectangle(10,10))); g2d.fill(newRoundRectangle2D.Double(155,30,75,100,50,50));

//dibujaarcoenformadepastelen2D,decolorblanco g2d.setPaint(Color.WHITE); g2d.setStroke(newBasicStroke(6.0f)); g2d.draw(newArc2D.Double(240,30,75,100,0,270,Arc2D.PIE));

//dibujalneas2Denverdeyamarillo g2d.setPaint(Color.GREEN); g2d.draw(newLine2D.Double(395,30,320,150));

//dibujalnea2Dusandoeltrazo floatguiones[]={10};//especificaelpatrndeguiones g2d.setPaint(Color.YELLOW); g2d.setStroke(newBasicStroke(4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,10,guiones,0)); g2d.draw(newLine2D.Double(320,30,395,150));

}//findelmtodopaintComponent }//findelaclaseFigurasJPanel Figura 12.29 | Figuras de Java 2D. (Parte 2 de 2). //Fig.12.30:Figuras.javaDemostracindealgunasfigurasdeJava2D. importjavax.swing.JFrame; publicclassFiguras{ //ejecutalaaplicacin publicstaticvoidmain(Stringargs[]){ //creamarcoparaobjetoFigurasJPanel JFramemarco=newJFrame("Dibujodefigurasen2D"); marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //creaobjetoFigurasJPanel FigurasJPanelfigurasJPanel=newFigurasJPanel(); marco.add(figurasJPanel);//agregafigurasJPaneltomarco marco.setSize(425,200);//estableceeltamaodelmarco marco.setVisible(true);//muestraelmarco }//findemain }//findelaclaseFiguras

Unidad13.Manejodeexcepciones
13.1Introduccin
Unaexcepcinesunaindicacindeunproblemaqueocurredurantelaejecucindeunprograma. Elmanejodeexcepcionespermitealosprogramadorescrearaplicacionesquepuedanresolverlasexcepciones.

13.2Generalidadesacercadelmanejodeexcepciones
El manejo de excepciones permite a los programadores eliminar el cdigo para manejar errores de la lnea principaldeejecucindelprograma,mejorandosuclaridadycapacidaddemodificacin. Realizar una tarea Si la tarea anterior no se ejecut correctamente Realizar el procesamiento de los errores Realizar la siguiente tarea Si la tarea anterior no se ejecut correctamente Realizar el procesamiento de los errores

13.3Ejemplo:divisinentrecerosinmanejodeexcepciones
Lasexcepcionesselanzancuandounmtododetectaunproblemaynopuedemanejarlo. El rastreo de la pila de una excepcin incluye el nombre de la excepcin en un mensaje descriptivo, el cual indica el problemaqueocurriylapiladellamadasamtodoscompleta(esdecir,lacadenadellamadas),enelmomentoen elqueocurrilaexcepcin. Elpuntoenelprogramaenelcualocurreunaexcepcinseconocecomopuntodelanzamiento.

//Fig.13.1:DivisionEntreCeroSinManejoDeExcepciones.java //Unaaplicacinquetrataderealizarunadivisinentrecero. importjava.util.Scanner; publicclassDivisionEntreCeroSinManejoDeExcepciones{ //demuestraellanzamientodeunaexcepcincuandoocurreunadivisinentrecero publicstaticintcociente(intnumerador,intdenominador){ returnnumerador/denominador;//posibledivisinentrecero }//findelmtodocociente publicstaticvoidmain(Stringargs[]){ Scannerexplorador=newScanner(System.in);//objetoScannerparaentrada System.out.print("Introduzcaunnumeradorentero:"); intnumerador=explorador.nextInt(); System.out.print("Introduzcaundenominadorentero:"); intdenominador=explorador.nextInt(); intresultado=cociente(numerador,denominador); System.out.printf( "\nResultado:%d/%d=%d\n",numerador,denominador,resultado); }//findemain }//findelaclaseDivisionEntreCeroSinManejoDeExcepciones

Introduzcaunnumeradorentero:100 Introduzcaundenominadorentero:7 Resultado:100/7=14

Introduzcaunnumeradorentero:100 Introduzcaundenominadorentero:0 Exceptioninthreadmainjava.lang.ArithmeticException:/byzero atDivisionEntreCeroSinManejoDeExcepciones.cociente( DivisionEntreCeroSinManejoDeExcepciones.java:10) atDivisionEntreCeroSinManejoDeExcepciones.main( DivisionEntreCeroSinManejoDeExcepciones.java:22) Introduzcaunnumeradorentero:100 Introduzcaundenominadorentero:hola Exceptioninthreadmainjava.util.InputMismatchException atjava.util.Scanner.throwFor(Scanner.java:840) atjava.util.Scanner.next(Scanner.java:1461) atjava.util.Scanner.nextInt(Scanner.java:2091) atjava.util.Scanner.nextInt(Scanner.java:2050) atDivisionEntreCeroSinManejoDeExcepciones.main( DivisionEntreCeroSinManejoDeExcepciones.java:20)

13.4Ejemplo:manejodeexcepcionestipoArithmeticExceptioneInputMismatchException
Un bloque try encierra el cdigo que podra lanzar una excepcin, y el cdigo que no debe ejecutarse si se produce esaexcepcin. Lasexcepcionespuedensurgiratravsdecdigomencionadoexplcitamenteenunbloquetry,atravsdellamadas aotrosmtodos,oinclusoatravsdellamadasamtodosanidados,iniciadasporelcdigoenelbloquetry. Un bloque catch empieza con la palabra clave catch y un parmetro de excepcin, seguido de un bloque de cdigo que atrapa (es decir, recibe) y maneja la excepcin. Este cdigo se ejecuta cuando el bloque try detecta la excepcin. Unaexcepcinnoatrapadaesunaexcepcinqueocurreyparalacualnohaybloquescatchquecoincidan. Una excepcin no atrapada har que un programa termine antesde tiempo, si ste slo contieneun subproceso.Si el programa contiene ms de un subproceso, slo terminar el subproceso en el que ocurri la excepcin. El resto delprogramaseejecutar,peropuedeproducirefectosadversos. Justodespusdelbloquetrydebeirporlomenosunbloquecatchounbloquefinally. Cadabloquecatchespecificaentreparntesisunparmetrodeexcepcin,elcualidentificaeltipodeexcepcinque puede procesar el manejador. El nombre del parmetro de excepcin permite al bloque catch interactuar con un objetodeexcepcinatrapada. Si ocurre una excepcin en un bloque try, ste termina de inmediato y el control del programa se transfiere al primero de los siguientes bloques catch cuyo parmetro de excepcin coincida con el tipo de la excepcin que se lanz. Unavezquesemanejaunaexcepcin,elcontroldelprogramanoregresaalpuntodelanzamiento,yaqueelbloque tryhaexpirado.Aestoseleconocecomoelmodelodeterminacindelmanejodeexcepciones. Sihayvariosbloquescatchquecoincidencuandoocurreunaexcepcin,sloseejecutaelprimero. Despus de ejecutar un bloque catch, el flujo de control del programa pasa a la siguiente instruccin despus del ltimobloquecatch. Unaclusulathrowsespecificalasexcepcionesquelanzaelmtodo,yaparecedespusdelalistadeparmetrosdel mtodo,peroantesdesucuerpo. La clusula throws contiene una lista separada por comas de excepciones que lanzar el mtodo, en caso de que ocurraunproblemacuandoelmtodoseejecute.

//Fig.13.2:DivisionEntreCeroConManejoDeExcepciones.java Unejemplodemanejodeexcepcionesqueverificaladivisinentrecero. importjava.util.InputMismatchException; importjava.util.Scanner;

publicclassDivisionEntreCeroConManejoDeExcepciones{ //demuestracmoselanzaunaexcepcincuandoocurreunadivisinentrecero publicstaticintcociente(intnumerador,intdenominador) throwsArithmeticException { returnnumerador/denominador;//posibledivisinentrecero }//findelmtodocociente publicstaticvoidmain(Stringargs[]){ Scannerexplorador=newScanner(System.in);//objetoScannerparaentrada booleancontinuarCiclo=true;//determinasisenecesitanmsdatosdeentrada

do{ try//leedosnmerosycalculaelcociente { System.out.print("Introduzcaunnumeradorentero:"); intnumerador=explorador.nextInt(); System.out.print("Introduzcaundenominadorentero:"); intdenominador=explorador.nextInt();

intresultado=cociente(numerador,denominador); System.out.printf("\nResultado:%d/%d=%d\n",numerador, denominador,resultado); continuarCiclo=false;//entradaexitosa;terminaelciclo }//findebloquetry catch(InputMismatchExceptioninputMismatchException) { System.err.printf("\nExcepcion:%s\n", inputMismatchException); explorador.nextLine();//descartaentradaparaqueelusuariointenteotravez System.out.println( "Debeintroducirenteros.Intentedenuevo.\n"); }//findebloquecatch catch(ArithmeticExceptionarithmeticException) { System.err.printf("\nExcepcion:%s\n",arithmeticException); System.out.println( "Ceroesundenominadorinvalido.Intentedenuevo.\n");

}//findecatch }while(continuarCiclo);//findedo...while }//findemain }//findelaclaseDivisionEntreCeroConManejoDeExcepciones

Introduzcaunnumeradorentero:100 Introduzcaundenominadorentero:7 Resultado: 100 / 7 = 14


Introduzca un numerador entero: 100 Introduzca un denominador entero: 0 Excepcion: java.lang.ArithmeticException: / by zero Cero es un denominador invalido. Intente de nuevo. Introduzca un numerador entero: 100 Introduzca un denominador entero: 7 Resultado: 100 / 7 = 14

Introduzca un numerador entero: 100 Introduzca un denominador entero: hola Excepcion: java.util.InputMismatchException Debe introducir enteros. Intente de nuevo. Introduzca un numerador entero: 100 Introduzca un denominador entero: 7 Resultado: 100 / 7 = 14

13.5Cundoutilizarelmanejodeexcepciones
Elmanejodeexcepcionesestdiseadoparaprocesarerroressincrnicos,queocurrencuandoseejecutauna instruccin. Elmanejodeexcepcionesnoestdiseadoparaprocesarlosproblemasasociadosconeventosasncronos,que ocurrenenparalelocon(yenformaindependientede)elflujodecontroldelprograma.

13.6JerarquadeexcepcionesdeJava
TodaslasclasesdeexcepcionesdeJavaheredan,yaseaenformadirectaoindirecta,delaclaseException.Debidoa esto,lasclasesdeexcepcionesdeJavaformanunajerarqua.Losprogramadorespuedenextenderestajerarqua paracrearsuspropiasclasesdeexcepciones. LaclaseThrowableeslasuperclasedelaclaseExceptiony,porlotanto,estambinlasuperclasedetodaslas excepciones.SlopuedenusarseobjetosThrowableconelmecanismoparamanejarexcepciones. LaclaseThrowabletienedossubclases:ExceptionyError. LaclaseExceptionysussubclasesrepresentansituacionesexcepcionalesquepodranocurrirenunprogramade Javayseratrapadosporlaaplicacin. LaclaseErrorytodassussubclasesrepresentansituacionesexcepcionalesquepodranocurrirenelsistemaen tiempodeejecucindeJava.LoserrorestipoErrorocurrenconpocafrecuenciay,porlogeneral,nodebenser atrapadosporunaaplicacin. Javaclasificaalasexcepcionesendoscategoras:verificadasynoverificadas. Adiferenciadelasexcepcionesverificadas,elcompiladordeJavanoverificaelcdigoparadeterminarsiuna excepcinnoverificadaseatrapaosedeclara.Porlogeneral,lasexcepcionesnoverificadassepuedenevitar medianteunacodificacinapropiada. Eltipodeunaexcepcindeterminasistaesverificadaonoverificada.Todoslostiposdeexcepcionesqueson subclasesdirectasoindirectasdelaclaseRuntimeExceptionsonexcepcionesnoverificadas.Todoslostiposde excepcionesqueheredandelaclaseExceptionperonodeRuntimeExceptionsonverificadas. Variasclasesdeexcepcionespuedenderivarsedeunasuperclasecomn.Siseescribeunbloquecatchparaatrapar losobjetosdeexcepcindeuntipodelasuperclase,tambinpuedeatraparatodoslosobjetosdelassubclasesde esaclase.Estopermiteelprocesamientopolimrficodelasexcepcionesrelacionadas.

13.7Bloquefinally
Los programas que obtienen ciertos tipos de recursos deben devolverlos al sistema de manera explcita, para evitar lasdenominadasfugasderecursos.Porlogeneral,elcdigoparaliberarrecursossecolocaenunbloquefinally. Elbloquefinallyesopcional.Siestpresente,secolocadespusdelltimobloquecatch. Javagarantizaquesiseproporcionaunbloquefinally,seejecutarsinimportarqueselanceonounaexcepcinen el bloque try correspondiente, o en uno de sus correspondientes bloques catch. Java tambin garantiza que un bloquefinallyseejecutarsiunbloquetrysalemedianteelusodeunainstruccinreturn,breakocontinue. Siunaexcepcinqueocurreenelbloquetrynosepuedeatraparmedianteunodelosmanejadorescatchasociados a ese bloque try, el programa ignora el resto del bloque try y el control pasa al bloque finally, que libera el recurso. Despus,elprogramapasaalsiguientebloquetryexterior;porlogeneral,enelmtodoquehacelallamada. Si un bloque catch lanza una excepcin, de todas formas se ejecuta el bloque finally. Despus, la excepcin se pasa alsiguientebloquetryexterior;porlogeneral,enelmtodoquehizolallamada. Losprogramadorespuedenlanzarexcepcionesmedianteelusodelainstruccinthrow. Una instruccin throw especifica un objeto a lanzar. El operando de una instruccin throw puede ser de cualquier clasequesederivedeThrowable.

//Fig.13.5:UsoDeExcepciones.java //Demostracindelmecanismodemanejodeexcepcionestry...catch...finally.

publicclassUsoDeExcepciones{ publicstaticvoidmain(Stringargs[]){ try { lanzaExcepcion();//llamaalmtodolanzaExcepcion }//findetry catch(Exceptionexcepcion)//excepcinlanzadaporlanzaExcepcion { System.err.println("Laexcepcionsemanejoenmain"); }//findecatch

noLanzaExcepcion(); }//findemain

Figura 13.5 Mecanismo de manejo de excepciones trycatchfinally. (Parte 1 de 2).

//demuestralosbloquestry...catch...finally publicstaticvoidlanzaExcepcion()throwsException{ try//lanzaunaexcepcinylaatrapadeinmediato { System.out.println("MetodolanzaExcepcion"); thrownewException();//generalaexcepcin }//findetry catch(Exceptionexcepcion)//atrapalaexcepcinlanzadaenelbloquetry { System.err.println( "LaexcepcionsemanejoenelmetodolanzaExcepcion"); throwexcepcion;//vuelvealanzarparaprocesarlamsadelante //nosellegaraalcdigocolocadoaqu,laexcepcinsevuelvealanzarenelbloquecatch }//findecatch finally//seejecutasinimportarloqueocurraenlosbloquestry...catch { System.err.println("SeejecutofinallyenlanzaExcepcion"); }//findefinally //nosellegaalcdigoquesecoloqueaqu }//findelmtodolanzaExcepcion //demuestraelusodefinallycuandonoocurreunaexcepcin publicstaticvoidnoLanzaExcepcion(){ try//elbloquetrynolanzaunaexcepcin { System.out.println("MetodonoLanzaExcepcion"); }//findetry catch(Exceptionexcepcion)//noseejecuta { System.err.println(excepcion); }//findecatch finally//seejecutasinimportarloqueocurraenlosbloquestry...catch { System.err.println( "SeejecutoFinallyennoLanzaExcepcion"); }//findebloquefinally System.out.println("FindelmetodonoLanzaExcepcion"); }//findelmtodonoLanzaExcepcion }//findelaclaseUsoDeExcepciones

Figura 13.5 Mecanismo de manejo de excepciones trycatchfinally. (Parte 2 de 2).


Metodo lanzaExcepcion La excepcion se manejo en el metodo lanzaExcepcion Se ejecuto finally en lanzaExcepcion La excepcion se manejo en main Metodo noLanzaExcepcion Se ejecuto Finally en noLanzaExcepcion Fin del metodo noLanzaExcepcion

13.8Limpiezadelapila
Las excepciones se vuelven a lanzar cuando un bloque catch, al momento de recibir una excepcin, decide que no puede procesarla, o que slo puede procesarla en forma parcial. Al volver a lanzar una excepcin se difiere el manejodeexcepciones(otalvezunapartedeste)aotrobloquecatch. Cuando se vuelve a lanzar una excepcin, el siguiente bloque try circundante detecta la excepcin que se volvi a lanzar,ylosbloquescatchdeesebloquetrytratandemanejarla. Cuando se lanza una excepcin, pero no se atrapa en un alcance especfico, se limpia la pila de llamadas a mtodos y se hace un intento por atrapar la excepcin en la siguiente instruccin try exterior. A este proceso se le conoce comolimpiezadelapila.

//Fig.13.6:UsoDeExcepciones.java //Demostracindelalimpiezadelapila. publicclassUsoDeExcepciones{ publicstaticvoidmain(Stringargs[]){ try//llamaalanzaExcepcionparademostrarlalimpiezadelapila { lanzaExcepcion(); }//findetry catch(Exceptionexcepcion)//excepcinlanzadaenlanzaExcepcion { System.err.println("Laexcepcionsemanejoenmain"); }//findecatch }//findemain //lanzaExcepcionlanzalaexcepcinquenoseatrapaenestemtodo publicstaticvoidlanzaExcepcion()throwsException { try//lanzaunaexcepcinylaatrapaenmain { System.out.println("MetodolanzaExcepcion"); thrownewException();//generalaexcepcin }//findetry catch(RuntimeExceptionruntimeException)//atrapaeltipoincorrecto { System.err.println( "LaexcepcionsemanejoenelmetodolanzaExcepcion"); }//findecatch finally//elbloquefinallysiempreseejecuta { System.err.println("Finallysiempreseejecuta"); }//findefinally }//findelmtodolanzaExcepcion }//findelaclaseUsoDeExcepciones

MetodolanzaExcepcion Finallysiempreseejecuta Laexcepcionsemanejoenmain

13.9printStackTrace,getStackTraceygetMessage
LaclaseThrowableofreceunmtodoprintStackTrace,queimprimelapiladellamadasamtodos.Amenudo,esto estilenlapruebaydepuracin. La clase Throwable tambin proporciona un mtodo getStackTrace, que obtiene informacin de rastreo de la pila, queprintStackTraceimprime. ElmtodogetMessagedelaclaseThrowabledevuelvelacadenadescriptivaalmacenadaenunaexcepcin. El mtodo getStackTrace obtiene la informacin de rastreo de la pila como un arreglo de objetos StackTraceElement. Cada objeto StackTraceElement representa una llamada a un mtodo en la pila de llamadas a mtodos. Los mtodos getClassName, getFileName, getLineNumber y getMethodName de la clase StackTraceElement obtienenelnombredelaclase,elnombredearchivo,elnmerodelneayelnombredelmtodo,respectivamente.

//Fig.13.7:UsoDeExcepciones.java //DemostracindegetMessageyprintStackTracedelaclaseException. publicclassUsoDeExcepciones{ publicstaticvoidmain(Stringargs[]){ try { metodo1();//llamaametodo1 }//findetry catch(Exceptionexcepcion)//atrapalaexcepcinlanzadaenmetodo1 { System.err.printf("%s\n\n",excepcion.getMessage()); excepcion.printStackTrace();//imprimeelrastreodelapiladelaexcepcin //obtienelainformacinderastreodelapila StackTraceElement[]elementosRastreo=excepcion.getStackTrace(); System.out.println("\nRastreodelapiladegetStackTrace:"); System.out.println("Clase\t\t\tArchivo\t\t\tLinea\tMetodo"); //iteraatravsdeelementosRastreoparaobtenerladescripcindelaexcepcin for(StackTraceElementelemento:elementosRastreo) { System.out.printf("%s\t",elemento.getClassName()); System.out.printf("%s\t",elemento.getFileName()); System.out.printf("%s\t",elemento.getLineNumber()); System.out.printf("%s\n",elemento.getMethodName()); }//findefor }//findecatch }//findemain //llamaametodo2;lanzalasexcepcionesdevueltaamain publicstaticvoidmetodo1()throwsException{ metodo2(); }//findelmtodometodo1 //llamaametodo3;lanzalasexcepcionesdevueltaametodo1 publicstaticvoidmetodo2()throwsException{ metodo3(); }//findelmtodometodo2 //lanzalaexcepcinExceptiondevueltaametodo2 publicstaticvoidmetodo3()throwsException { thrownewException("Laexcepcionselanzoenmetodo3"); }//findelmtodometodo3 }//findelaclaseUsoDeExcepciones

La excepcion se lanzo en metodo3 java.lang.Exception: La excepcion se lanzo en metodo3 at UsoDeExcepciones.metodo3(UsoDeExcepciones.java:49) at UsoDeExcepciones.metodo2(UsoDeExcepciones.java:43) at UsoDeExcepciones.metodo1(UsoDeExcepciones.java:37) at UsoDeExcepciones.main(UsoDeExcepciones.java:10) Rastreo de la pila de getStackTrace: Clase Archivo UsoDeExcepciones UsoDeExcepciones.java UsoDeExcepciones UsoDeExcepciones.java UsoDeExcepciones UsoDeExcepciones.java UsoDeExcepciones UsoDeExcepciones.java Linea 49 43 37 10 Metodo metodo3 metodo2 metodo1 main

13.10Excepcionesencadenadas Lasexcepcionesencadenadaspermitenqueunobjetodeexcepcinmantengalainformacinderastreo delapilacompleta,incluyendolainformacinacercadelasexcepcionesanterioresqueprovocaronla excepcinactual.

//Fig.13.8:UsoDeExcepcionesEncadenadas.javaDemostracindelasexcepcionesencadenadas.

publicclassUsoDeExcepcionesEncadenadas{ publicstaticvoidmain(Stringargs[]){ try { metodo1();//llamaametodo1 }//findetry catch(Exceptionexcepcion)//excepcioneslanzadasdesdemetodo1 { excepcion.printStackTrace(); }//findecatch }//findemain

//llamaametodo2;lanzalasexcepcionesdevueltaamain publicstaticvoidmetodo1()throwsException{ try { metodo2();//llamaametodo2 }//findetry catch(Exceptionexcepcion)//excepcinlanzadadesdemetodo2 { thrownewException("Laexcepcionselanzoenmetodo1",excepcion); }//findetry }//findelmtodometodo1

//llamaametodo3;lanzalasexcepcionesdevueltaametodo1 publicstaticvoidmetodo2()throwsException{ try { metodo3();//llamaametodo3 }//findetry catch(Exceptionexcepcion)//excepcinlanzadadesdemetodo3 { thrownewException("Laexcepcionselanzoenmetodo2",excepcion); }//findecatch }//findelmtodometodo2

//lanzaexcepcinExceptiondevueltaametodo2 publicstaticvoidmetodo3()throwsException{ thrownewException("Laexcepcionselanzoenmetodo3"); }//findelmtodometodo3 }//findelaclaseUsoDeExcepcionesEncadenadas

13.11Declaracindenuevostiposdeexcepciones Unanuevaclasedeexcepcindebeextenderaunaclasedeexcepcinexistente,paraasegurarquela clasepuedausarseconelmecanismodemanejodeexcepciones. 13.12Precondicionesyposcondiciones Laprecondicindeunmtodoesunacondicinquedebeserverdaderaalmomentodeinvocarel mtodo. Laposcondicindeunmtodoesunacondicinqueesverdaderaunavezqueregresaelmtodocon xito. Aldisearsuspropiosmtodos,debeestablecerlasprecondicionesyposcondicionesenuncomentario antesdeladeclaracindelmtodo. 13.13Aserciones Dentro de una aplicacin, los programadores pueden establecer condiciones que asuman como verdaderas en un punto especfico. Estas condiciones, conocidas como aserciones, ayudan a asegurar la validezdeunprogramaalatraparerrorespotencialeseidentificarposibleserroreslgicos. Java incluye dos versiones de una instruccin assert para validar las aserciones mediante la programacin. Parahabilitarlasasercionesentiempodeejecucin,useelmodificadoreaalejecutarelcomandojava. //Fig.13.9:PruebaAssert.java //Usodeassertparaverificarqueunvalorabsolutoseapositivo importjava.util.Scanner; publicclassPruebaAssert{ publicstaticvoidmain(Stringargs[]){ Scannerentrada=newScanner(System.in); System.out.print("Escribaunnumeroentre0y10:"); intnumero=entrada.nextInt(); //aseguraqueelvalorabsolutosea>=0 assert(numero>=0&&numero<=10):"numeroincorrecto:"+numero; System.out.printf("Ustedescribio%d\n",numero); }//findemain }//findelaclasePruebaAssert Escribaunnumeroentre0y10:5 Ustedescribio5 Escribaunnumeroentre0y10:50 Exceptioninthread"main"java.lang.AssertionError:numeroincorrecto:50 atPruebaAssert.main(PruebaAssert.java:15)

Unidad14.ArchivosyFlujos

14.1Introduccin
Los datos que se almacenan en variables y arreglos son temporales; se pierden cuando una variable local queda fuera de alcance, o cuando el programa termina. Las computadoras utilizan archivos para la retencin a largo plazo de grandes cantidadesdedatos,inclusodespusdequelosprogramasquecrearonlosdatosterminandeejecutarse. Losdatospersistentesquesemantienenenarchivosexistenmsalldeladuracindelaejecucindelprograma. Lascomputadorasalmacenanlosarchivosendispositivosdealmacenamientosecundario,comolosdiscosduros.

14.2Jerarquadedatos
El elemento de datos ms pequeo en una computadora puede asumir el valor 0 o 1, y se le conoce como bit. En ltima instancia,unacomputadoraprocesatodosloselementosdedatoscomocombinacionesdecerosyunos. Elconjuntodecaracteresdelacomputadoraeselconjuntodetodosloscaracteresqueseutilizanparaescribirprogramas yrepresentardatos. LoscaracteresenJavasonUnicodeyestncompuestosdedosbytes,cadaunodeloscualessecomponedeochobits. Ascomo loscaracteresestncompuestosdebits,loscampossecomponen decaracteresobytes.Uncampoesungrupo decaracteresobytesquetransmiteunsignificado. Los elementos de datos procesados por las computadoras forman una jerarqua de datos, la cual se vuelve ms grande y complejaenestructura,amedidaqueprogresamosdebitsacaracteres,luegoacampos,yasenlosucesivo. Porlogeneral,varioscamposcomponenunregistro(queseimplementacomoclassenJava). Unregistroesungrupodecamposrelacionados. Unarchivoesungrupoderegistrosrelacionados. Para facilitar la obtencin de registros especficos de un archivo, se elige por lo menos un campo en cada registro como clave. Una clave de registro identifica que un registro pertenece a una persona o entidad especfica, y es nico para cada registro. Existen muchas formas de organizar los registros en un archivo. La ms comn se llama archivo secuencial, en el cual los registrossealmacenanenorden,enbasealcampoclavederegistro. Porlo general, aungrupodearchivosrelacionadosseledenominabasededatos.Unacoleccindeprogramasdiseados paracrearyadministrarbasesdedatosseconocecomosistemadeadministracindebasesdedatos(DBMS).

14.3Archivosyflujos
Javaveacadaarchivocomounflujosecuencialdebytes. Cada sistema operativo cuenta con un mecanismo para determinar el fi n de un archivo, como un marcador de fi n de archivoolacuentadelosbytestotalesenelarchivo,queseregistraenunaestructuradedatosadministrativa,manejada porelsistema. Losflujosbasadosenbytesrepresentandatosenformatobinario. Losflujosbasadosencaracteresrepresentandatoscomosecuenciasdecaracteres. Los archivos que se crean usando flujos basados en bytes son archivos binarios. Los archivos que se crean usando flujos basados en caracteres son archivos de texto. Los archivos de texto se pueden leer mediante editores de texto, mientras quelosarchivosbinariosseleenmedianteunprogramaqueconvierteesosdatosenunformatolegibleparaloshumanos. Java tambin puede asociar los flujos con distintos dispositivos. Tres objetos flujo se asocian con dispositivos cuando un programadeJavaempiezaaejecutarse:System.in,System.outySystem.err. Elpaquetejava.ioincluyedefinicionesparalasclasesdeflujos,comoFileInputStream(paralaentradabasadaenbytesde un archivo), FileOutputStream (para la salida basada en bytes hacia un archivo), FileReader (para la entrada basada en caracteresdeunarchivo)yFileWriter(paralasalidabasadaencaractereshaciaunarchivo).Losarchivosseabrencreando objetosdeestasclasesdeflujos. LaclaseFileseutilizaparaobtenerinformacinacercadelosarchivosydirectorios. LasoperacionesdeentradaysalidabasadasencaracteressepuedenllevaracaboconlasclasesScanneryFormatter. La clase Formatter permite mostrar datos con formato en la pantalla, o enviarlos a un archivo, de una manera similar a System.out.printf. Larutadeunarchivoodirectorioespecificasuubicacineneldisco. Una ruta absoluta contiene todos los directorios, empezando con el directorio raz, que conducen hacia un archivo o directorioespecfico.Cadaarchivoodirectorioenunaunidaddediscotieneelmismodirectoriorazensuruta. Porlogeneral,unarutarelativaempiezadesdeeldirectorioenelqueseempezaejecutarlaaplicacin. Uncarcterseparadorseutilizaparaseparardirectoriosyarchivosenlaruta.

14.4LaclaseFile

//Fig.14.4:DemostracionFile.java //DemostracindelaclaseFile. importjava.io.File; publicclassDemostracionFile{ //muestrainformacinacercadelarchivoespecificadoporelusuario publicvoidanalizarRuta(Stringruta){ //creaunobjetoFileconbaseenlaentradadelusuario Filenombre=newFile(ruta); if(nombre.exists())//siexisteelnombre,muestrainformacinsobrel { //muestrainformacindelarchivo(odirectorio) System.out.printf( "%s%s\n%s\n%s\n%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s", nombre.getName(),"existe", (nombre.isFile()?"esunarchivo":"noesunarchivo"), (nombre.isDirectory()?"esundirectorio": "noesundirectorio"), (nombre.isAbsolute()?"esrutaabsoluta": "noesrutaabsoluta"),"Ultimamodificacion:", nombre.lastModified(),"Tamanio:",nombre.length(), "Ruta:",nombre.getPath(),"Rutaabsoluta:", nombre.getAbsolutePath(),"Padre:",nombre.getParent()); if(nombre.isDirectory())//muestraellistadodeldirectorio { Stringdirectorio[]=nombre.list(); System.out.println("\n\nContenidodeldirectorio:\n"); for(StringnombreDirectorio:directorio) System.out.printf("%s\n",nombreDirectorio); }//findeelse }//findeifexterior else//noesarchivoodirectorio,muestramensajedeerror { System.out.printf("%s%s",ruta,"noexiste."); }//findeelse }//findelmtodoanalizarRuta }//findelaclaseDemostracionFile //Fig.14.5:PruebaDemostracionFile.javaPruebadelaclaseDemostracionFile. importjava.util.Scanner; importjava.io.File; importjava.net.URI; publicclassPrueba{ publicstaticvoidmain(Stringargs[]){ try { FiletestFile=newFile("C:\\books\\2004\\sjhtp7e\\frame\\jhtp7_14_Files.fm"); System.out.println(testFile.toURI().toString()); } catch(Exceptionexception) { System.out.println("exception"); }

}//endmain }//endclassPrueba

Escriba aqui el nombre del archivo o directorio: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc jfc existe no es un archivo es un directorio es ruta absoluta Ultima modificacion: 1187324492359 Tamanio: 0 Ruta: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc Ruta absoluta: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc Padre: C:\Archivos de programa\Java\jdk1.6.0_01\demo Contenido del directorio: CodePointIM FileChooserDemo Font2DTest Java2D Metalworks Notepad SampleTree Stylepad SwingApplet SwingSet2 TableExample

Escriba aqui el nombre del archivo o directorio: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc\Java2D\readme.txt readme.txt existe es un archivo no es un directorio es ruta absoluta Ultima modificacion: 1187324491203 7518 Tamanio: Ruta: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc\Java2D\readme.txt Ruta absoluta: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc\Java2D\readme.txt Padre: C:\Archivos de programa\Java\jdk1.6.0_01\demo\jfc\Java2D

14.5Archivosdetextodeaccesosecuencial
Javanoimponeunaestructuraenunarchivo;lasnocionescomolosregistrosnoexistencomopartedellenguajede Java.Elprogramadordebeestructurarlosarchivosparasatisfacerlosrequerimientosdeunaaplicacin. Para obtener datos de un archivo en forma secuencial, los programas comnmente empiezan a leer desde el principiodelarchivoyleentodoslosdatosenformaconsecutiva,hastaencontrarlainformacindeseada. Los datos en muchos archivos secuenciales no se pueden modificar sin el riesgo de destruir otros datos en el archivo. Por lo tanto, los registros en un archivo de acceso secuencial normalmente no se actualizan directamente ensuubicacin.Envezdeello,sevuelveaescribirelarchivocompleto.

//Fig.14.5:RegistroCuenta.javaUnaclasequerepresentaunregistrodeinformacin packagecom.deitel.jhtp7.cap14;//seempaquetaparareutilizarla

publicclassRegistroCuenta{ privateintcuenta; privateStringprimerNombre; privateStringapellidoPaterno; privatedoublesaldo; publicRegistroCuenta(){ //elconstructorsinargumentosllamaaotroconstructorconvalorespredeterminados this(0,"","",0.0);//llamaalconstructorconcuatroargumentos }//findelconstructordeRegistroCuentasinargumentos //inicializaunregistro publicRegistroCuenta(intcta,Stringnombre,Stringapellido,doublesal){ establecerCuenta(cta); establecerPrimerNombre(nombre); establecerApellidoPaterno(apellido); establecerSaldo(sal); }//findelconstructordeRegistroCuentaconcuatroargumentos

Figura 14.6 | RegistroCuenta mantiene la informacin para una cuenta. (Parte 1 de 2).

//estableceelnmerodecuenta publicvoidestablecerCuenta(intcta){ cuenta=cta; }//findelmtodoestablecerCuenta //obtieneelnmerodecuenta publicintobtenerCuenta(){ returncuenta; }//findelmtodoobtenerCuenta //estableceelprimernombre publicvoidestablecerPrimerNombre(Stringnombre){ primerNombre=nombre; }//findelmtodoestablecerPrimerNombre //obtieneelprimernombre publicStringobtenerPrimerNombre(){ returnprimerNombre; }//findelmtodoobtenerPrimerNombre //estableceelapellidopaterno publicvoidestablecerApellidoPaterno(Stringapellido){ apellidoPaterno=apellido; }//findelmtodoestablecerApellidoPaterno //obtieneelapellidopaterno publicStringobtenerApellidoPaterno(){ returnapellidoPaterno; }//findelmtodoobtenerApellidoPaterno //estableceelsaldo publicvoidestablecerSaldo(doublesal){ saldo=sal; }//findelmtodoestablecerSaldo //obtieneelsaldo publicdoubleobtenerSaldo(){ returnsaldo; }//findelmtodoobtenerSaldo }//findelaclaseRegistroCuenta

Figura 14.6 | RegistroCuenta mantiene la informacin para una cuenta. (Parte 2 de 2).

//Fig.14.7:CrearArchivoTexto.java //UsodelaclaseFormatterparaescribirdatosenunarchivodetexto. importjava.io.FileNotFoundException; importjava.lang.SecurityException; importjava.util.Formatter; importjava.util.FormatterClosedException; importjava.util.NoSuchElementException; importjava.util.Scanner; importcom.deitel.jhtp7.cap14.RegistroCuenta; publicclassCrearArchivoTexto{ privateFormattersalida;//objetousadoparaenviartextoalarchivo Figura 14.7 | Creacin de un archivo de texto secuencial. (Parte 1 de 2).

//permitealusuarioabrirelarchivo publicvoidabrirArchivo(){ try{ salida=newFormatter("clientes.txt"); }//findetry catch(SecurityExceptionsecurityException){ System.err.println("Notieneaccesodeescrituraaestearchivo."); System.exit(1); }//findecatch catch(FileNotFoundExceptionfilesNotFoundException){ System.err.println("Erroralcrearelarchivo."); System.exit(1); }//findecatch }//findelmtodoabrirArchivo

//agregaregistrosalarchivo publicvoidagregarRegistros(){ //objetoquesevaaescribirenelarchivo RegistroCuentaregistro=newRegistroCuenta();

Scannerentrada=newScanner(System.in);

System.out.printf("%s\n%s\n%s\n%s\n\n", "Paraterminarlaentrada,escribaelindicadordefindearchivo","cuandoselepidaqueescribalosdatosdeentrada.", "EnUNIX/Linux/MacOSXescriba<ctrl>dyoprimaIntro","EnWindowsescriba<ctrl>zyoprimaIntro");

System.out.printf("%s\n%s","Escribaelnumerodecuenta(>0),primernombre,apellidopaternoysaldo.","?");

while(entrada.hasNext()){//iterahastaencontrarelindicadordefindearchivo try{//envavaloresalarchivo //obtienelosdatosquesevanaenviar registro.establecerCuenta(entrada.nextInt());//leeelnmerodecuenta registro.establecerPrimerNombre(entrada.next());//leeelprimernombre registro.establecerApellidoPaterno(entrada.next());//leeelapellidopaterno registro.establecerSaldo(entrada.nextDouble());//leeelsaldo

if(registro.obtenerCuenta()>0){ //escribeelnuevoregistro salida.format("%d%s%s%.2f\n",registro.obtenerCuenta(),registro.obtenerPrimerNombre(), registro.obtenerApellidoPaterno(),registro.obtenerSaldo()); }//findeif else{ System.out.println("Elnumerodecuentadebesermayorque0."); }//findeelse }//findetry catch(FormatterClosedExceptionformatterClosedException){ System.err.println("Erroralescribirenelarchivo."); return; }//findecatch catch(NoSuchElementExceptionelementException){ System.err.println("Entradainvalida.Intentedenuevo."); entrada.nextLine();//descartalaentradaparaqueelusuariointentedenuevo }//findecatch

System.out.printf("%s%s\n%s","Escribaelnumerodecuenta(>0),","primernombre,apellidopaternoysaldo.","?"); }//findewhile }//findelmtodoagregarRegistros

Figura 14.7 | Creacin de un archivo de texto secuencial. (Parte 2 de 2).

publicvoidcerrarArchivo(){//cierraelfile if(salida!=null) salida.close(); }//findelmtodocerrarArchivo }//findelaclaseCrearArchivoTexto

//Fig.14.9:PruebaCrearArchivoTexto.javaPruebadelaclaseCrearArchivoTexto.

publicclassPruebaCrearArchivoTexto{ publicstaticvoidmain(Stringargs[]){ CrearArchivoTextoaplicacion=newCrearArchivoTexto();

aplicacion.abrirArchivo(); aplicacion.agregarRegistros(); aplicacion.cerrarArchivo();

}//findemain }//findelaclasePruebaCrearArchivoTexto Para terminar la entrada, escriba el indicador de fin de archivo cuando se le pida que escriba los datos de entrada. En UNIX/Linux/Mac OS X escriba <ctrl> d y oprima Intro En Windows escriba <ctrl> z y oprima Intro Escriba el numero de cuenta (> 0), primer nombre, apellido paterno y saldo. ? 100 Bob Jones 24.98 Escriba el numero de cuenta (> 0), primer nombre, apellido paterno y saldo. ? 200 Steve Doe -345.67 Escriba el numero de cuenta (> 0), primer nombre, apellido paterno y saldo. ? 300 Pam White 0.00 Escriba el numero de cuenta (> 0), primer nombre, apellido paterno y saldo. ? 400 Sam Stone -42.16 Escriba el numero de cuenta (> 0), primer nombre, apellido paterno y saldo. ? 500 Sue Rich 224.62 Escriba el numero de cuenta (> 0), primer nombre, apellido paterno y saldo. ? ^Z

14.5.2Cmoleerdatosdeunarchivodetextodeaccesosecuencial //Fig.14.11:LeerArchivoTexto.javaEsteprogramaleeunarchivodetextoymuestracadaregistro. importjava.io.File; importjava.io.FileNotFoundException; importjava.lang.IllegalStateException; importjava.util.NoSuchElementException; importjava.util.Scanner; importcom.deitel.jhtp7.cap14.RegistroCuenta; publicclassLeerArchivoTexto{ privateScannerentrada; //permitealusuarioabrirelarchivo publicvoidabrirArchivo(){ try{ entrada=newScanner(newFile("clientes.txt")); }//findetry catch(FileNotFoundExceptionfileNotFoundException){ System.err.println("Erroralabrirelarchivo."); System.exit(1); }//findecatch }//findelmtodoabrirArchivo //leeregistrodelarchivo publicvoidleerRegistros(){ //objetoquesevaaescribirenlapantalla RegistroCuentaregistro=newRegistroCuenta(); System.out.printf("%9s%15s%18s%10s\n","Cuenta","Primernombre","Apellidopaterno","Saldo"); try//leeregistrosdelarchivo,usandoelobjetoScanner { while(entrada.hasNext()){ registro.establecerCuenta(entrada.nextInt());//leeelnmerodecuenta registro.establecerPrimerNombre(entrada.next());//leeelprimernombre registro.establecerApellidoPaterno(entrada.next());//leeelapellidopaterno registro.establecerSaldo(entrada.nextDouble());//leeelsaldo //muestraelcontenidodelregistro System.out.printf("%9d%15s%18s%10.2f\n",

registro.obtenerCuenta(),registro.obtenerPrimerNombre(), registro.obtenerApellidoPaterno(),registro.obtenerSaldo()); }//findewhile }//findetry catch(NoSuchElementExceptionelementException){ System.err.println("Elarchivonoestabienformado."); entrada.close(); System.exit(1); }//findecatch catch(IllegalStateExceptionstateException){ System.err.println("Erroralleerdelarchivo."); System.exit(1); }//findecatch }//findelmtodoleerRegistros

publicvoidcerrarArchivo(){//cierraelarchivoyterminalaaplicacin if(entrada!=null) entrada.close();//cierraelarchivo

}//findelmtodocerrarArchivo }//findelaclaseLeerArchivoTexto

//Fig.14.12:PruebaLeerArchivoTexto.javaEsteprogramapruebalaclaseLeerArchivoTexto. publicclassPruebaLeerArchivoTexto{ publicstaticvoidmain(Stringargs[]){ LeerArchivoTextoaplicacion=newLeerArchivoTexto(); aplicacion.abrirArchivo(); aplicacion.leerRegistros(); aplicacion.cerrarArchivo(); }//findemain }//findelaclasePruebaLeerArchivoTexto

Cuenta Primernombre 100 Bob 200 Steve 300 Pam 400 Sam 500 Sue

Apellidopaterno Jones Doe White Stone Rich

Saldo 24.98 345.67 0.00 42.16 224.62

14.5.3Ejemploprctico:unprogramadesolicituddecrdito

//Fig.14.13:OpcionMenu.javaDefineuntipoenumparalasopcionesdelprogramadeconsultadecrdito. publicenumOpcionMenu{ //declaraelcontenidodeltipoenum SALDO_CERO(1), SALDO_CREDITO(2), SALDO_DEBITO(3), FIN(4);

privatefinalintvalor;//opcinactualdelmen

OpcionMenu(intvalorOpcion){ valor=valorOpcion; }//findelconstructordeltipoenumOpcionMenu publicintobtenerValor(){ returnvalor; }//findelmtodoobtenerValor }//findeltipoenumOpcionMenu //Fig.14.14:ConsultaCredito.javaEsteprogramaleeunarchivosecuencialmenteymuestrasucontenidoconbaseeneltipo //decuentaquesolicitaelusuario(saldoconcrdito,saldocondbitoosaldodecero). importjava.io.File; importjava.io.FileNotFoundException; importjava.lang.IllegalStateException; importjava.util.NoSuchElementException; importjava.util.Scanner;

publicclassConsultaCredito{

importcom.deitel.jhtp7.cap14.RegistroCuenta;

privateOpcionMenutipoCuenta; privateScannerentrada; privateOpcionMenuopciones[]={OpcionMenu.SALDO_CERO, OpcionMenu.SALDO_CREDITO,OpcionMenu.SALDO_DEBITO, OpcionMenu.FIN}; Figura 14.14 | Programa de consulta de crdito. (Parte 1 de 3).

//leelosregistrosdelarchivoymuestraslolosregistrosdeltipoapropiado privatevoidleerRegistros(){ //objetoquesevaaescribirenelarchivo RegistroCuentaregistro=newRegistroCuenta(); try{//leeregistros //abreelarchivoparaleerdesdeelprincipio entrada=newScanner(newFile("clientes.txt")); while(entrada.hasNext()){//recibelosvaloresdelarchivo registro.establecerCuenta(entrada.nextInt());//leenmerodecuenta registro.establecerPrimerNombre(entrada.next());//leeprimernombre registro.establecerApellidoPaterno(entrada.next());//leeapellidopaterno registro.establecerSaldo(entrada.nextDouble());//leesaldo //sieltipodecuentaesapropiado,muestraelregistro if(debeMostrar(registro.obtenerSaldo())) System.out.printf("%10d%12s%12s%10.2f\n",registro.obtenerCuenta(),registro.obtenerPrimerNombre(), registro.obtenerApellidoPaterno(),registro.obtenerSaldo()); }//findewhile }//findetry catch(NoSuchElementExceptionelementException){ System.err.println("Elarchivonoestabienformado."); entrada.close(); System.exit(1); }//findecatch catch(IllegalStateExceptionstateException){ System.err.println("Erroralleerdelarchivo."); System.exit(1); }//findecatch catch(FileNotFoundExceptionfileNotFoundException){ System.err.println("Nosepuedeencontrarelarchivo."); System.exit(1); }//findecatch finally { if(entrada!=null) entrada.close();//cierraelobjetoScanneryelarchivo }//findefinally }//findelmtodoleerRegistros //usaeltipoderegistroparadeterminarsielregistrodebemostrarse privatebooleandebeMostrar(doublesaldo){ if((tipoCuenta==OpcionMenu.SALDO_CREDITO)&&(saldo<0)) returntrue; elseif((tipoCuenta==OpcionMenu.SALDO_DEBITO)&&(saldo>0)) returntrue; elseif((tipoCuenta==OpcionMenu.SALDO_CERO)&&(saldo==0)) returntrue; returnfalse; }//findelmtododebeMostrar //obtienesolicituddelusuario privateOpcionMenuobtenerSolicitud(){ ScannertextoEnt=newScanner(System.in); intsolicitud=1; Figura 14.14 | Programa de consulta de crdito. (Parte 2 de 3).

//muestraopcionesdesolicitud System.out.printf("\n%s\n%s\n%s\n%s\n%s\n", "Escribasolicitud","1Listadecuentasconsaldosdecero", "2Listadecuentasconsaldosconcredito", "3Listadecuentasconsaldoscondebito","4Finalizarejecucion"); try//trataderecibirlaopcindelmen { do//recibesolicituddelusuario { System.out.print("\n?"); solicitud=textoEnt.nextInt(); }while((solicitud<1)||(solicitud>4)); }//findetry catch(NoSuchElementExceptionelementException){ System.err.println("Entradainvalida."); System.exit(1); }//findecatch returnopciones[solicitud1];//devuelvevalordeenumparalaopcin }//findelmtodoobtenerSolicitud publicvoidprocesarSolicitudes(){ //obtienelasolicituddelusuario(saldodecero,concrditoocondbito) tipoCuenta=obtenerSolicitud(); while(tipoCuenta!=OpcionMenu.FIN){ switch(tipoCuenta){ caseSALDO_CERO: System.out.println("\nCuentasconsaldosdecero:\n"); break; caseSALDO_CREDITO: System.out.println("\nCuentasconsaldosconcredito:\n"); break; caseSALDO_DEBITO: System.out.println("\nCuentasconsaldoscondebito:\n"); break; }//findeswitch leerRegistros(); tipoCuenta=obtenerSolicitud(); }//findewhile }//findelmtodoprocesarSolicitudes }//findelaclaseConsultaCredito //Fig.14.15:PruebaConsultaCredito.java //EsteprogramapruebalaclaseConsultaCredito. publicclassPruebaConsultaCredito{ publicstaticvoidmain(Stringargs[]){ ConsultaCreditoaplicacion=newConsultaCredito(); aplicacion.procesarSolicitudes(); } }//findemain }//findelaclasePruebaConsultaCredito

Escriba solicitud 1 - Lista de cuentas con saldos de cero 2 - Lista de cuentas con saldos con credito 3 - Lista de cuentas con saldos con debito 4 - Finalizar ejecucin ?1 Cuentas con saldos de cero: 300 Pam White 0.00 Escriba solicitud 1 - Lista de cuentas con saldos de cero 2 - Lista de cuentas con saldos con credito 3 - Lista de cuentas con saldos con debito 4 - Finalizar ejecucin ?2 con saldos con credito: Cuentas 200 Steve Doe -345.67 400 Sam Stone -42.16 Escriba solicitud 1 - Lista de cuentas con saldos de cero - Lista de cuentas con saldos con credito 2 3 - Lista de cuentas con saldos con debito 4 - Finalizar ejecucin ?3 Cuentas con saldos con debito: 100 Bob Jones 24.98 Sue Rich 224.62 500 ? 4 14.6Serializacindeobjetos
Java cuenta con un mecanismo llamado Serializacin de objetos, el cual permite escribir o leer objetos completos medianteunflujo. Un objeto serializado es un objeto que se representa como una secuencia de bytes, e incluye los datos del objeto, ascomoinformacinacercadeltipodelobjetoylostiposdedatosalmacenadosenelmismo. Una vez que se escribe un objeto serializado en un archivo, se puede leer del archivo y deserializarse; es decir, se puedeutilizarlainformacindetipoylosbytesquerepresentanalobjetopararecrearloenlamemoria. Las clases ObjectInputStream y ObjectOutputStream, que implementan en forma respectiva a las interfaces ObjectInputyObjectOutput,permitenleeroescribirobjetoscompletosde/aunflujo(posiblementeunarchivo). Slo las clases que implementan a la interfaz Serializable pueden serializarse y deserializarse con objetos ObjectOutputStreamyObjectInputStream.

14.6.1CreacindeunarchivodeaccesosecuencialmedianteelusodelaSerializacindeobjetos
//Fig.14.17:RegistroCuentaSerializable.javaUnaclasequerepresentaunregistrodeinformacin. packagecom.deitel.jhtp7.cap14;//empaquetadaparareutilizarla

importjava.io.Serializable;

publicclassRegistroCuentaSerializableimplementsSerializable{ privateintcuenta; privateStringprimerNombre; privateStringapellidoPaterno; privatedoublesaldo;

//elconstructorsinargumentosllamaalotroconstructorconvalorespredeterminados publicRegistroCuentaSerializable(){ this(0,"","",0.0); }//findelconstructordeRegistroCuentaSerializablesinargumentos

Figura 14.17 | La clase RegistroCuentaSerializable para los objetos serializables. (Parte 1 de 2).

//elconstructorconcuatroargumentosinicializaunregistro publicRegistroCuentaSerializable(intcta,Stringnombre,Stringapellido,doublesal){ establecerCuenta(cta); establecerPrimerNombre(nombre); establecerApellidoPaterno(apellido); establecerSaldo(sal); }//findelconstructordeRegistroCuentaSerializableconcuatroargumentos

publicvoidestablecerCuenta(intcta){//estableceelnmerodecuenta cuenta=cta; }//findelmtodoestablecerCuenta

publicintobtenerCuenta(){//obtieneelnmerodecuenta returncuenta; }//findelmtodoobtenerCuenta publicvoidestablecerPrimerNombre(Stringnombre){//estableceelprimernombre primerNombre=nombre; }//findelmtodoestablecerPrimerNombre

publicStringobtenerPrimerNombre(){//obtieneelprimernombre returnprimerNombre; }//findelmtodoobtenerPrimerNombre

publicvoidestablecerApellidoPaterno(Stringapellido){//estableceelapellidopaterno apellidoPaterno=apellido; }//findelmtodoestablecerApellidoPaterno

publicStringobtenerApellidoPaterno(){//obtieneelapellidopaterno returnapellidoPaterno; }//findelmtodoobtenerApellidoPaterno

publicvoidestablecerSaldo(doublesal){//estableceelsaldo saldo=sal; }//findelmtodoestablecerSaldo

publicdoubleobtenerSaldo(){//obtieneelsaldo returnsaldo; }//findelmtodoobtenerSaldo }//findelaclaseRegistroCuentaSerializable

Figura 14.17 | La clase RegistroCuentaSerializable para los objetos serializables. (Parte 2 de 2). //Fig.14.18:CrearArchivoSecuencial.javaEscrituradeobjetosenformasecuencialaunarchivo,conlaclase ObjectOutputStream. importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.ObjectOutputStream; importjava.util.NoSuchElementException; importjava.util.Scanner; importcom.deitel.jhtp7.cap14.RegistroCuentaSerializable; publicclassCrearArchivoSecuencial{ privateObjectOutputStreamsalida;//envalosdatosaunarchivo Figura14.18|ArchivosecuencialcreadomedianteObjectOutputStream.(Parte1de2).

publicvoidabrirArchivo(){//permitealusuarioespecificarelnombredelarchivo try{//abreelarchivo salida=newObjectOutputStream(newFileOutputStream("clientes.ser")); }//findetry catch(IOExceptionioException){ System.err.println("Erroralabrirelarchivo."); }//findecatch }//findelmtodoabrirArchivo

publicvoidagregarRegistros(){//agregaregistrosalarchivo RegistroCuentaSerializableregistro;//objetoquesevaaescribiralarchivo intnumeroCuenta=0;//nmerodecuentaparaelobjetoregistro StringprimerNombre;//primernombreparaelobjetoregistro StringapellidoPaterno;//apellidopaternoparaelobjetoregistro doublesaldo;//saldoparaelobjetoregistro

Scannerentrada=newScanner(System.in);

System.out.printf("%s\n%s\n%s\n%s\n\n", "Paraterminardeintroducirdatos,escribaelindicadordefindearchivo","Cuandoselepidaqueintroduzcalosdatos.", "EnUNIX/Linux/MacOSXescriba<ctrl>dyoprimaIntro","EnWindowsescriba<ctrl>zyoprimaIntro");

System.out.printf("%s\n%s","Escribaelnumerodecuenta(>0),primernombre,apellidoysaldo.","?");

while(entrada.hasNext()){//iterahastaelindicadordefindearchivo try{//envalosvaloresalarchivo numeroCuenta=entrada.nextInt();//leeelnmerodecuenta primerNombre=entrada.next();//leeelprimernombre apellidoPaterno=entrada.next();//leeelapellidopaterno saldo=entrada.nextDouble();//leeelsaldo if(numeroCuenta>0){ //creaunregistronuevo registro=newRegistroCuentaSerializable(numeroCuenta,primerNombre,apellidoPaterno,saldo); salida.writeObject(registro);//envaelregistrocomosalida }//findeif else{ System.out.println("Elnumerodecuentadebesermayorde0."); }//findeelse }//findetry catch(IOExceptionioException){ System.err.println("Erroralescribirenelarchivo."); return; }//findecatch catch(NoSuchElementExceptionelementException){ System.err.println("Entradainvalida.Intentedenuevo."); entrada.nextLine();//descartalaentradaparaqueelusuariointentedenuevo }//findecatch System.out.printf("%s%s\n%s","Escribaelnumerodecuenta(>0),","primernombre,apellidoysaldo.","?"); }//findewhile }//findelmtodoagregarRegistros publicvoidcerrarArchivo(){//cierraelarchivoyterminalaaplicacin try{//cierraelarchivo if(salida!=null) salida.close(); }//findetry catch(IOExceptionioException){ System.err.println("Erroralcerrarelarchivo."); System.exit(1); }//findecatch }//findelmtodocerrarArchivo }//findelaclaseCrearArchivoSecuencial

//Fig.14.19:PruebaCrearArchivoSecuencial.java //PruebadelaclaseCrearArchivoSecuencial.

publicclassPruebaCrearArchivoSecuencial{ publicstaticvoidmain(Stringargs[]){ CrearArchivoSecuencialaplicacion=newCrearArchivoSecuencial();

aplicacion.abrirArchivo(); aplicacion.agregarRegistros(); aplicacion.cerrarArchivo();

}//findemain }//findelaclasePruebaCrearArchivoSecuencial Para terminar de introducir datos, escriba el indicador de fin de archivo cuando se le pida que introduzca los datos. En UNIX/Linux/Mac OS X escriba <ctrl> d y oprima Intro En Windows escriba <ctrl> z y oprima Intro Escriba el numero de cuenta (> 0), primer nombre, apellido y saldo. ? 100 Bob Jones 24.98 Escriba el numero de cuenta (> 0), primer nombre, apellido y saldo. ? 200 Steve Doe -345.67 Escriba el numero de cuenta (> 0), primer nombre, apellido y saldo. ? 300 Pam White 0.00 Escriba el numero de cuenta (> 0), primer nombre, apellido y saldo. ? 400 Sam Stone -42.16 Escriba el numero de cuenta (> 0), primer nombre, apellido y saldo. ? 500 Sue Rich 224.62 Escriba el numero de cuenta (> 0), primer nombre, apellido y saldo. ? ^Z

14.6.2LecturaydeserializacindedatosdeunarchivodeaccesoSecuencial
//Fig.14.20:LeerArchivoSecuencial.java //Esteprogramaleeunarchivodeobjetosenformasecuencialymuestracadaregistro. importjava.io.EOFException; importjava.io.FileInputStream; importjava.io.IOException; importjava.io.ObjectInputStream;

importcom.deitel.jhtp7.cap14.RegistroCuentaSerializable;

publicclassLeerArchivoSecuencial{ privateObjectInputStreamentrada; //permitealusuarioseleccionarelarchivoaabrir publicvoidabrirArchivo(){ try{//abreelarchivo entrada=newObjectInputStream(newFileInputStream("clientes.ser")); }//findetry catch(IOExceptionioException){ System.err.println("Erroralabrirelarchivo."); }//findecatch }//findelmtodoabrirArchivo //leeelregistrodelarchivo publicvoidleerRegistros(){ RegistroCuentaSerializableregistro; System.out.printf("%10s%15s%15s%10s\n","Cuenta","Primernombre","Apellidopaterno","Saldo");

Figura 14.20 | Lectura de un archivo secuencial, usando un objeto ObjectInputStream. (Parte 1 de 2).

try{//recibelosvaloresdelarchivo while(true){ registro=(RegistroCuentaSerializable)entrada.readObject(); //muestraelcontenidodelregistro System.out.printf("%10d%15s%15s%11.2f\n", registro.obtenerCuenta(),registro.obtenerPrimerNombre(),registro.obtenerApellidoPaterno(),registro.obtenerSaldo()); }//findewhile }//findetry catch(EOFExceptionendOfFileException){ return;//sellegalfindelarchivo }//findecatch catch(ClassNotFoundExceptionclassNotFoundException){ System.err.println("Nosepudocrearelobjeto."); }//findecatch catch(IOExceptionioException){ System.err.println("Erroralleerdelarchivo."); }//findecatch }//findelmtodoleerRegistros //cierraelarchivoyterminalaaplicacin publicvoidcerrarArchivo(){ try{//cierraelarchivoysale if(entrada!=null) entrada.close(); System.exit(0); }//findetry catch(IOExceptionioException){ System.err.println("Erroralcerrarelarchivo."); System.exit(1); }//findecatch }//findelmtodocerrarArchivo }//findelaclaseLeerArchivoSecuencial

Figura 14.20 | Lectura de un archivo secuencial, usando un objeto ObjectInputStream. (Parte 2 de 2). //Fig.14.21:PruebaLeerArchivoSecuencial.java //EsteprogramapruebalaclaseReadSequentialFile. publicclassPruebaLeerArchivoSecuencial{ publicstaticvoidmain(Stringargs[]){ LeerArchivoSecuencialaplicacion=newLeerArchivoSecuencial(); aplicacion.abrirArchivo(); aplicacion.leerRegistros(); aplicacion.cerrarArchivo(); }//findemain }//findelaclasePruebaLeerArchivoSecuencial

14.7Clasesadicionalesdejava.io
La interfaz ObjectOutput contiene el mtodo writeObject, el cual recibe un objeto Object que implementa a la interfazSerializablecomoargumentoyescribesuinformacinenunobjetoOutputStream. LainterfazObjectInputcontieneelmtodoreadObject,queleeydevuelveunareferenciaaunobjetoObjectdeun objetoInputStream.Unavezquesehaledounobjeto,sureferenciapuedeconvertirsealtipoactualdelobjeto. El uso de bfer es una tcnica para mejorar el rendimiento de E/S. Con un objeto BufferedOutputStream, cada instruccin de salida no necesariamente produce una transferencia fsica real de datos al dispositivo de salida. En vez de ello, cada operacin de salida se dirige hacia una regin en memoria llamada bfer, la cual es lo bastante grande como para contener los datos de muchas operaciones de salida. La transferencia actual al dispositivo de salidaserealizaentoncesenunasolaoperacindesalidafsicaextensacadavezquesellenaelbfer. Con un objeto BufferedInputStream, muchos trozos lgicos de datos de un archivo se leen como una sola operacin de entrada fsica extensa y se colocan en un bfer de memoria. A medida que un programa solicita cada nuevo trozo de datos, se obtiene del bfer. Cuando el bfer est vaco, se lleva a cabo la siguiente operacin de entradafsicarealdesdeeldispositivodeentrada,paraleerelnuevogrupodetrozoslgicosdedatos.

14.8AbrirarchivosconJFileChooser
La clase JFileChooser se utiliza para mostrar un cuadro de dilogo, que permite a los usuarios de un programa seleccionararchivosconfacilidad,medianteunaGUI. //Fig.14.22:DemostracionFile.javaDemostracindelaclaseFile. importjava.awt.BorderLayout; importjava.awt.event.ActionEvent; importjava.awt.event.ActionListener; importjava.io.File; importjavax.swing.JFileChooser; importjavax.swing.JFrame; importjavax.swing.JOptionPane; importjavax.swing.JScrollPane; importjavax.swing.JTextArea; importjavax.swing.JTextField; publicclassDemostracionFileextendsJFrame{ privateJTextAreaareaSalida;//seutilizaparasalida privateJScrollPanepanelDespl;//seutilizaparaquelasalidapuedadesplazarse //establecelaGUI publicDemostracionFile(){ super("PruebadelaclaseFile"); areaSalida=newJTextArea(); //agregaareaSalidaapanelDespl panelDespl=newJScrollPane(areaSalida); add(panelDespl,BorderLayout.CENTER);//agregapanelDesplalaGUI setSize(400,400);//estableceeltamaodelaGUI setVisible(true);//muestralaGUI analizarRuta();//creayanalizaunobjetoFile }//findelconstructordeDemostracionFile //permitealusuarioespecificarelnombredelarchivo privateFileobtenerArchivo(){ //muestraelcuadrodedilogodearchivos,paraqueelusuariopuedaelegirelarchivoaabrir JFileChooserselectorArchivos=newJFileChooser(); selectorArchivos.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES); Figura 14.22 | Demostracin de JFileChooser. (Parte 1 de 2).

intresultado=selectorArchivos.showOpenDialog(this); //sielusuariohizoclicenelbotnCancelarenelcuadrodedilogo,regresa if(resultado==JFileChooser.CANCEL_OPTION) System.exit(1); FilenombreArchivo=selectorArchivos.getSelectedFile();//obtieneelarchivoseleccionado //muestraerrorsiesinvlido if((nombreArchivo==null)||(nombreArchivo.getName().equals(""))){ JOptionPane.showMessageDialog(this,"Nombredearchivoinvlido", "Nombredearchivoinvlido",JOptionPane.ERROR_MESSAGE); System.exit(1); }//findeif returnnombreArchivo; }//findelmtodoobtenerArchivo //muestrainformacinacercadelarchivoqueespecificaelusuario publicvoidanalizarRuta(){ //creaunobjetoFilebasadoenlaentradadelusuario Filenombre=obtenerArchivo(); if(nombre.exists()){//sielnombreexiste,muestrainformacinsobrel //muestralainformacinsobreelarchivo(odirectorio) areaSalida.setText(String.format("%s%s\n%s\n%s\n%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s", nombre.getName(),"existe", (nombre.isFile()?"esunarchivo":"noesunarchivo"), (nombre.isDirectory()?"esundirectorio":"noesundirectorio"), (nombre.isAbsolute()?"esunarutaabsoluta":"noesunarutaabsoluta"),"Ultimamodificacion:", nombre.lastModified(),"Tamanio:",nombre.length(), "Ruta:",nombre.getPath(),"Rutaabsoluta:", nombre.getAbsolutePath(),"Padre:",nombre.getParent())); if(nombre.isDirectory()){//imprimeellistadodeldirectorio Stringdirectorio[]=nombre.list(); areaSalida.append("\n\nContenidodeldirectorio:\n"); for(StringnombreDirectorio:directorio) areaSalida.append(nombreDirectorio+"\n"); }//findeelse }//findeifexterior else//noesarchivonidirectorio,imprimemensajedeerror { JOptionPane.showMessageDialog(this,nombre+ "noexiste.","ERROR",JOptionPane.ERROR_MESSAGE); }//findeelse }//findelmtodoanalizarRuta }//findelaclaseDemostracionFile

//Fig.14.23:PruebaDemostracionFile.javaPruebadelaclaseDemostracionFile. importjavax.swing.JFrame;

publicclassPruebaDemostracionFile{ publicstaticvoidmain(Stringargs[]){ DemostracionFileaplicacion=newDemostracionFile(); aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}//findemain }//findelaclasePruebaDemostracionFile

Unidad15.Recursividad
15.1Introduccin
Unmtodorecursivosellamaasmismoenformadirectaoindirectaatravsdeotromtodo. Cuandosellamaaunmtodorecursivopararesolverunproblema,enrealidadelmtodoescapazderesolverslo el(los)caso(s)mssimple(s),ocaso(s)base.Sisellamaconuncasobase,elmtododevuelveunresultado.

15.2Conceptosderecursividad
Sisellamaaunmtodorecursivoconunproblemamscomplejoqueelcasobase,porlogeneral,divideel problemaendospiezasconceptuales:unapiezaqueelmtodosabecmoresolveryotrapiezaquenosabecmo resolver. Paraquelarecursividadseafactible,lapiezaqueelmtodonosabecmoresolverdebeasemejarsealproblema original,perodebeserunaversinligeramentemssimpleopequeadelmismo.Comoestenuevoproblemase parecealproblemaoriginal,elmtodollamaaunanuevacopiadesmismoparatrabajarenelproblemams pequeo;aestoseleconocecomopasorecursivo. Paraquelarecursividadtermineenunmomentodado,cadavezqueunmtodosellameasmismoconuna versinmssimpledelproblemaoriginal,lasecuenciadeproblemascadavezmspequeosdebeconvergerenun casobase. Cuandoelmtodoreconoceelcasobase,devuelveunresultadoalacopiaanteriordelmtodo. Unallamadarecursivapuedeserunallamadaaotromtodo,queasuvezrealizaunallamadadevueltaalmtodo original.Dichoprocesosigueprovocandounallamadarecursivaalmtodooriginal.Aestoseleconocecomo llamadarecursivaindirecta,orecursividadindirecta.

15.3Ejemplodeusoderecursividad:factoriales
Laaccindeomitirelcasobase,oescribirelpasorecursivodemaneraincorrectaparaquenoconverjaenelcaso base,puedeocasionarunarecursividadinfinita,conlocualseagotalamemoriaenciertopunto.Esteerrores anlogoalproblemadeuncicloinfinitoenunasoluciniterativa(norecursiva).

15.4Ejemplodeusoderecursividad:seriedeFibonacci
LaseriedeFibonacciempiezacon0y1,ytienelapropiedaddequecadanmerosubsiguientedeFibonacciesla sumadelosdosanteriores. LaproporcindenmerosdeFibonaccisucesivosconvergeenunvalorconstantede1.618,unnmeroalquesele denominalaproporcindorada,omediadorada. Algunassolucionesrecursivas,comoladeFibonacci(querealizadosllamadasporcadapasorecursivo),producen unaexplosindellamadasamtodos.

//Fig.15.3:CalculoFactorial.javaMtodofactorialrecursivo. publicclassCalculoFactorial{ //declaracinrecursivadelmtodofactorial publiclongfactorial(longnumero){ if(numero<=1)//evalaelcasobase return1;//casosbase:0!=1y1!=1 else//pasorecursivo returnnumero*factorial(numero1); }//findelmtodofactorial //imprimefactorialesparalosvaloresdel0al10 publicvoidmostrarFactoriales(){ //calculalosfactorialesdel0al10 for(intcontador=0;contador<=10;contador++) System.out.printf("%d!=%d\n",contador,factorial(contador)); }//findelmtodomostrarFactoriales }//findelaclaseCalculoFactorial

//Fig.15.4:PruebaFactorial.javaPruebadelmtodorecursivofactorial.

publicclassPruebaFactorial{ //calculalosfactorialesdel0al10 publicstaticvoidmain(Stringargs[]){ CalculoFactorialcalculoFactorial=newCalculoFactorial(); calculoFactorial.mostrarFactoriales(); }//findelmtodomain }//findelaclasePruebaFactorial 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800

------------------------------------------------------------------------------------------------//Fig.15.5:CalculoFibonacci.javaMtodofibonaccirecursivo. publicclassCalculoFibonacci{ //declaracinrecursivadelmtodofibonacci publiclongfibonacci(longnumero){ if((numero==0)||(numero==1))//casosbase returnnumero; else//pasorecursivo returnfibonacci(numero1)+fibonacci(numero2); }//findelmtodofibonacci publicvoidmostrarFibonacci(){ for(intcontador=0;contador<=10;contador++) System.out.printf("Fibonaccide%des:%d\n",contador, fibonacci(contador)); }//findelmtodomostrarFibonacci }//findelaclaseCalculoFibonacci

//Fig.15.6:PruebaFibonacci.javaPruebadelmtodorecursivofibonacci. publicclassPruebaFibonacci{ publicstaticvoidmain(Stringargs[]){ CalculoFibonaccicalculoFibonacci=newCalculoFibonacci(); calculoFibonacci.mostrarFibonacci(); }//findemain }//findelaclasePruebaFibonacci Fibonacci de 0 es: 0 Fibonacci de 1 es: 1 Fibonacci de 2 es: 1 Fibonacci de 3 es: 2 Fibonacci de 4 es: 3 Fibonacci de 5 es: 5 Fibonacci de 6 es: 8 Fibonacci de 7 es: 13 Fibonacci de 8 es: 21 Fibonacci de 9 es: 34 Fibonacci de 10 es: 55

Evite los programas recursivos al estilo de Fibonacci, ya que producen una explosin exponencial de llamadas a mtodos.

15.5Larecursividadylapiladellamadasamtodos
Unapilaesunaestructuradedatosenlaqueslosepuedenagregaroeliminardatosdelapartesuperior. Una pila es la analoga de un montn de platos. Cuando se coloca un plato en el montn, siempre se coloca en la parte superior (a esto se le conoce como meter el plato en la pila). De manera similar, cuando se quita un plato del montn,siempresequitadelapartesuperior(aestoseleconocecomosacarelplatodelapila). Las pilas se conocen como estructuras dedatos ltimoen entrar, primero en salir (UEPS):el ltimo elementoque semeti(insert)enlapilaeselprimeroquesesaca(elimina)deella. Laspilastienenmuchasaplicacionesinteresantes.Porejemplo,cuandounprogramallamaaunmtodo,elmtodo que se llam debe saber cmo regresar al que lo llam, por lo que se mete la direccin de retorno del mtodo que hizo la llamada en la pilade ejecucindel programa (a la que algunas veces se le conoce como lapila de llamadas a mtodos). La pila de ejecucin del programa contiene la memoria para las variables locales en cada invocacin de un mtodo, durante la ejecucin de un programa. Estos datos, que se almacenan como una parte de la pila de ejecucin del programa,seconocencomoelregistrodeactivacinomarcodepiladelallamadaalmtodo. Si hay ms llamadas a mtodos recursivas o anidadas de las que pueden almacenarse en la pila de ejecucin del programa,seproduceunerrorconocidocomodesbordamientodepila.

15.6Comparacinentrerecursividadeiteracin

Tantolaiteracincomolarecursividadsebasanenunainstruccindecontrol:laiteracinutilizaunainstruccinde repeticin,larecursividadunainstruccindeseleccin. Tantolaiteracincomolarecursividadimplicanlarepeticin:laiteracinutilizademaneraexplcitaunainstruccin derepeticin,mientrasquelarecursividadlogralarepeticinatravsdellamadasrepetidasaunmtodo. La iteracin y la recursividad implican una prueba de terminacin: la iteracin termina cuando falla la condicin de continuacindeciclo,larecursividadcuandosereconoceuncasobase. La iteracin con repeticin controlada por contador y la recursividad se acercan en forma gradual a la terminacin: la iteracin sigue modificando un contador, hasta que ste asume un valor que hace que falle la condicin de continuacindeciclo,mientrasquelarecursividadsigueproduciendoversionescadavezmssimplesdelproblema original,hastallegaralcasobase. Tantolaiteracincomolarecursividadpuedenocurrirenformainfinita.Uncicloinfinitoocurreconlaiteracinsila prueba de continuacin de ciclo nunca se vuelve falsa, mientras que la recursividad infinita ocurre si el paso recursivonoreduceelproblemacadavezms,deunaformaqueconverjaenelcasobase. La recursividad invoca el mecanismo en forma repetida, y en consecuencia a la sobrecarga producida por las llamadasalmtodo. Por lo general se prefi ere un mtodo recursivo en vez de uno iterativo cuando el primero refleja el problema con msnaturalidad,yproduceunprogramamsfcildecomprenderydedepurar. A menudo se puede implementar un mtodo recursivo con pocas lneas de cdigo, pero el mtodo iterativo correspondiente podra requerir una gran cantidad de cdigo. Otra razn por la que es ms conveniente elegir una solucinrecursivaesqueunasoluciniterativapodranoseraparente.

//Fig.15.10:CalculoFactorial.javaMtodofactorialiterativo.

publicclassCalculoFactorial{ //declaracinrecursivadelmtodofactorial publiclongfactorial(longnumero){ longresultado=1;

//declaraciniterativadelmtodofactorial for(longi=numero;i>=1;i) resultado*=i; returnresultado; }//findelmtodofactorial

//muestralosfactorialesparalosvaloresdel0al10 publicvoidmostrarFactoriales(){ //calculalosfactorialesdel0al10 for(intcontador=0;contador<=10;contador++) System.out.printf("%d!=%d\n",contador,factorial(contador)); }//findelmtodomostrarFactoriales }//findelaclaseCalculoFactorial

//Fig.15.11:PruebaFactorial.javaPruebadelmtodofactorialiterativo. publicclassPruebaFactorial{ //calculalosfactorialesdel0al10 publicstaticvoidmain(Stringargs[]){ CalculoFactorialcalculoFactorial=newCalculoFactorial(); calculoFactorial.mostrarFactoriales(); }//findemain }//findelaclasePruebaFactorial

0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800

15.7LastorresdeHanoi

1. Mover n -- 1 discos de la aguja 1 a la aguja 2, usando la aguja 3 como un rea de almacenamiento temporal. 2. Mover el ltimo disco (el ms grande) de la aguja 1 a la aguja 3. 3. Mover n -- 1 discos de la aguja 2 a la aguja 3, usando la aguja 1 como rea de almacenamiento temporal.

//Fig.15.13:TorresDeHanoi.javaProgramaqueresuelveelproblemadelastorresdeHanoi,ydemuestralarecursividad.

publicclassTorresDeHanoi{ privateintnumDiscos;//nmerodediscosamover publicTorresDeHanoi(intdiscos){ numDiscos=discos; }//findelconstructordeTorresDeHanoi

//muevediscosdeunatorreaotra,demanerarecursiva publicvoidresolverTorres(intdiscos,intagujaOrigen,intagujaDestino,intagujaTemp){ //casobaseslohayquemoverundisco if(discos==1){ System.out.printf("\n%d>%d",agujaOrigen,agujaDestino); return; }//findeif

//pasorecursivomueve(disco1)discosdeagujaOrigenaagujaTempusandoagujaDestino resolverTorres(discos1,agujaOrigen,agujaTemp,agujaDestino);

//mueveelltimodiscodeagujaOrigenaagujaDestino System.out.printf("\n%d>%d",agujaOrigen,agujaDestino);

//mueve(discos1)discosdeagujaTempaagujaDestino resolverTorres(discos1,agujaTemp,agujaDestino,agujaOrigen); }//findelmtodoresolverTorres }//findelaclaseTorresDeHanoi

//Fig.15.14:PruebaTorresDeHanoi.javaPruebalasolucinalproblemadelastorresdeHanoi. publicclassPruebaTorresDeHanoi{ publicstaticvoidmain(Stringargs[]){ intagujaInicial=1;//seusaelvalor1paraindicaragujaInicialenlasalida intagujaFinal=3;//seusaelvalor3paraindicaragujaFinalenlasalida intagujaTemp=2;//seusaelvalor2paraindicaragujaTempenlasalida inttotalDiscos=3;//nmerodediscos TorresDeHanoitorresDeHanoi=newTorresDeHanoi(totalDiscos); //llamadanorecursivainicial:muevetodoslosdiscos. torresDeHanoi.resolverTorres(totalDiscos,agujaInicial,agujaFinal,agujaTemp); }//findemain }//findelaclasePruebaTorresDeHanoi

1 --> 3 1 --> 2 3 --> 2 1 --> 3 2 --> 1 2 --> 3 1 --> 3

15.8 Fractales
o Un fractal es una figura geomtrica que se genera a partir de un patrn que se repite en forma recursiva, un nmero infinito de veces. o Los fractales tienen una propiedad de auto-similitud: las subpartes son copias de tamao reducido de toda la pieza.

Pg.66

15.9Vueltaatrsrecursiva(backtracking)
Alusodelarecursividadpararegresaraunpuntodedecisinanteriorseleconocecomovueltaatrsrecursiva.Si un conjunto de llamadas recursivas no produce como resultado una solucin al problema, el programa retrocede hasta el punto de decisin anterior y toma una decisin distinta, lo cual a menudo produce otro conjunto de llamadasrecursivas.

Potrebbero piacerti anche