Está en la página 1de 43

ndicedecontenido

7.6ManejodeEventos.....................................................................................................................2 7.6.2Adaptadoresyclasesinternasparamanejodeeventos......................................................4 7.6.3Threadsyelmanejodeeventos..........................................................................................6 7.7Controladoresdedistribucin....................................................................................................7 8.JDBC..............................................................................................................................................12 8.1Creacindeunatabladeunabasededatos.............................................................................13 8.2Extraccindeinformacindeunatabla...................................................................................15 8.3ConectarunprogramaJavaconunabasededatos..................................................................17 8.4Lacomunicacinconunabasededatos..................................................................................18 8.5Actualizacindeunabasededatos..........................................................................................18 8.6Consultasaunabasededatos..................................................................................................18 8.7Sentenciaspreparadas.............................................................................................................19 8.8Metadatos................................................................................................................................20 8.9Transacciones..........................................................................................................................21 8.10Procedimientosentablas........................................................................................................21 8.11EquivalenciadetiposentreJavaySQL.................................................................................22 8.12ExcepcionesJDBC.................................................................................................................23 8.13CumplimientoSQL................................................................................................................24 9.JavaBeans.......................................................................................................................................24 9.2JavaBeans.................................................................................................................................25 9.2.1Conceptos.........................................................................................................................26 9.2.2Propiedades......................................................................................................................26 9.3LainformacindeunBean......................................................................................................28 9.4PropiedadesdeunBean...........................................................................................................29 9.4.1Propiedadescompartidas..................................................................................................30 9.5Eventos.....................................................................................................................................35 10.ArchivosJAR................................................................................................................................41 10.1CmocrearunJAR................................................................................................................42 10.2InvocacindearchivosJAR...................................................................................................42 10.3Archivomanifiesto.................................................................................................................43

7.6ManejodeEventos
TantoAWTcomoSwingtienenencomnunsistemaparaelmanejodeloseventosqueseproducencuando elusuariointeractaconlainterfazgrfica.Elfuncionamientodelmodelodeeventossebasaenlagestinde excepciones. Paracadaobjetoquerepresenteunainterfazgrfica,sepuedendefinirobjetos"oyentes"(listeners),que esperenaquesucedaundeterminadoeventosobrelainterfaz.Cadavezqueelusuariotecleauncaractero pulsaunbotndelratn,ocurreunevento.Cualquieroyentepuedesernotificadodelevento.Todoloque tienequehaceresimplementarlainterface(paraelmanejodelevento)apropiadayserregistradocomoun oyentedeeventodeleventofuenteapropiado.LoscomponentesSwingpuedegenerarmuchasclasesde evento.Loseventospuedenserlosquesemuestranenlasiguientetabla. Interface ActionListener CaretListener ChangeListener ComponentListener Claseadaptador1 ninguna ninguna ninguna ComponentAdapter Paquete java.awt.event javax.swing.event javax.swing.event java.awt.event Mtodos actionPerformed caretUpdate stateChanged componentHidden componentMoved componentResized componentShown componentAdded componentRemoved changedUpdate insertUpdate removeUpdate focusGained focusLost internalFrameActivated internalFrameClosed internalFrameClosing internalFrameDeactivated internalFrameDeiconified internalFrameIconified internalFrameOpened itemStateChanged keyPressed keyReleased keyTyped valueChanged mouseClicked mouseEntered mouseExited mousePressed mouseReleased mouseDragged

ContainerListener DocumentListener FocusListener

ContainerAdapter ninguna FocusAdapter

java.awt.event javax.swing.event java.awt.event

InternalFrameListener

InternalFrameAdapter

javax.swing.event

ItemListener KeyListener ListSelectionListener

ninguna KeyAdapter ninguna MouseAdapter MouseInputAdapter MouseMotionAdapter

java.awt.event java.awt.event javax.swing.event java.awt.event javax.swing.event java.awt.event

MouseListener

MouseMotionListener
1

Unadaptador(adapter)esunpatrndediseo.RealmenteesunaclaseJavaqueimplementaunainterfaceconunconjuntodemtodosvacos.As sepuedecrearunasubclasedeladaptadorysobreescribirlosmtodosdeseados,sinimplementartodoslosmtodos.Elusomscomndelos adaptadoresesparaelmanejodeeventos.conKeyAdapter,FocusAdapter,WindowAdapter,etc.nosetienenqueescribirlosmtodosqueno interesan.

UndoableEditListener

MouseInputAdapter ninguna

javax.swing.event javax.swing.event

WindowListener

WindowAdapter

java.awt.event

mouseMoved undoableEditHappened windowActivated windowClosed windowClosing windowDeactivated windowDeiconified windowIconified windowOpened

LaclasebaseparatodosestoseventosquesepuedenlanzareslaclaseAWTEvent(pertenecientealpaquete java.awt).ElmodelodeeventosdeAWTdependedelpaquetejava.awt.event,queenSwingseamplaconel paquetejavax.swing.event. Existendostiposbsicosdeeventos: Fsicos:Correspondenauneventohardwareclaramenteidentificable.Porejemplo,si:sehapulsado unatecla(KeyStrokeEvent),sehapresionadoelmouse,etc. Semnticos:Secomponendeunconjuntodeeventosfsicos,quesucedidosenundeterminadoorden tienenunsignificadomsabstracto.Porejemplo,sielusuariohaelegidounelementodeunalista desplegable(ItemEvent),etc. Ejemplodeeventospuedenser: activarcomponentes(ActionEvent) presionar/soltarbotonesdelmouse(MouseEvent) minimizar,maximizar,cerrarolanzarunaventanahaciaatrs(WindowEvent). teclear(KeyEvent). presionarenter seleccionaruntemdeunalista seleccionaruntemenunmen etc. Cadaeventoestrepresentadoporunobjetoqueofreceinformacinsobreeleventoeidentificalafuente.Las fuentesdeloseventosnormalmentesoncomponentes,perootrostiposdeobjetostambinpuedenserfuente deeventos.Comomuestralasiguientefigura,cadafuentedeeventopuedetenervariosoyentesregistrados. Inversamente,unslooyentepuederegistrarseconvariasfuentesdeeventos. Variosoyentespuedenser registradosparasernotificadosdeeventosdeuntipoparticularsobreunafuenteparticular.
fuentedel evento objeto evento oyentede evento oyentede evento oyentede evento

Figura8.8.1.Registrodeoyentesparaunevento.

7.6.1Implementacindeunmanejadordeeventos
Todomanejadordeeventosrequieretrespartesdecdigo:
3

1. Dondesedeclarelaclasedelmanejadordeeventos.Elcdigoespecificaquelaclaseimplementaun
interfacedeoyenteodesciendeunaclasequeimplementauninterfacedeoyente.Porejemplo: publicclassMiClaseEventoimplementsActionListener{...}

2. Elcdigoqueregistraunejemplardelaclasedemanejodeeventosdeunoyentesobreunooms
componentes.Porejemplo. componentCualquiera.addActionListener(instanciadeMiClaseEvento);

3. Laimplementacindelosmtodosdelainterfaceoyente.Porejemplo.
publicvoidactionPerformed(ActionEvente){ ...//codigoqueseejecutaracuandoocurraelevento } Unescenariodemanejodeeventostpicoocurreconlosbotones(JButton).Paradetectarcuandoelusuario pulsaunbotndelapantalla(opulsalateclaequivalente),elprogramadebetenerunobjetoqueimplementa lainterfaceActionListener.Elprogramadeberegistraresteobjetocomounoyentedeaccindelbotn (lafuentedelevento),usandoelmtodo addActionListener.Cuandoelusuariopulsaelbotndela pantalla, stedisparaelevento Action, storesultaenunallamadaalmtodo actionPerformed del oyentedeAction(elnicomtododelainterfaceActionListener).Elnicoargumentodelmtodo esunobjetoActionEventqueofreceinformacinsobreeleventoysufuente.Lasecuenciaseveenla siguientefigura.
JButton ActionEvent ActionListener

Figura8.8.2.Cuandoelusuariopulsaunbotn,losoyentesdeactiondelbotnsonnotificados.

Los manejadores de eventos pueden ser ejemplares de cualquier clase. Frecuentemente, se implementan usandoclasesinternasannimas(clasesinner).

7.6.2Adaptadoresyclasesinternasparamanejodeeventos
Lamayoradelasinterfacesdeoyentes,alcontrarioquelos ActionListener,contienenmsdeun mtodo. Por ejemplo, la interface MouseListener contiene cinco mtodos: mousePressed, mouseReleased, mouseEntered, mouseExited, y mouseClicked. Si slo han de considerarselaspulsacionesylaclaseimplementadirectamentelainterfaceMouseListener,entoncesse deben implementar los cinco mtodos de MouseListener. Aquellos mtodos de eventos que no te interesanpuedentenerloscuerposvacos.Porejemplo.
publicclassMyClassimplementsMouseListener{ ... someObject.addMouseListener(this); ... //implementacionvaciadelmetodo publicvoidmousePressed(MouseEvente){ } //implementacionvaciadelmetodo publicvoidmouseReleased(MouseEvente){
4

} //implementacionvaciadelmetodo publicvoidmouseEntered(MouseEvente){ } //implementacionvaciadelmetodo publicvoidmouseExited(MouseEvente){ } //UNICOmetodoqueseimplementa publicvoidmouseClicked(MouseEvente){ //elmanejodeleventiriaaqui } }

Desafortunadamente,lacoleccindecuerposdemtodosvacosresultantepuederesultardifcildeleeryde mantener. Para evitar esta confusin de cdigo con cuerpos de mtodos vacos, el AWT y Swing proporcionanunaclaseadapterporcadainterfacedeoyenteconmsdeunmtodo.Porejemplo,laclase MouseAdapterimplementaelinterfaceMouseListener.Unaclaseadaptadorimplementaversionesvacasde todoslosmtodosdelainterface. Parausarunadaptadorsecreaunasubclase,enlugardeimplementardirectamenteunainterfacedeoyente. Porejemplo,extendiendolaclaseMouseAdapter,laclaseheredadefinicionesvacasparalosmtodosque contieneMouseListener.
publicclassMyClassextendsMouseAdapter{ ... someObject.addMouseListener(this); ... publicvoidmouseClicked(MouseEvente){ //elmanejodeleventiriaaqui } }

Enelsupuestocasodequesedesearaquelaclasemanejaraeventosdelmouseperoquenodescendieradeun adaptador,setendraqueemplearunaclaseinterna(inner)quedesciendadelaclaseMouseAdapter.Por ejemplo:


... someObject.addMouseListener(newMyAdapter()); ... classMyAdapterextendsMouseAdapter{ publicvoidmouseClicked(MouseEvente){ //elmanejodeleventiriaaqui } } }

enelejemploanteriorsecreaunainstanciadeunobjeto MyAdapter(claseinterna,cuyadefinicinesten lamismaclase).Otramaneradehacerloescrearelobjetodirectamentedelaclase MouseAdapter y definirelmtodomouseClicked().Porejemplo:


... someObject.addMouseListener(newMouseAdapter(){ publicvoidmouseClicked(MouseEvente){ //elmanejodeleventiriaaqui } });
5

... } }

Estosoloesaplicablecuandouneventotendrauncomportamientonico,generadoporunsolocomponente. Encaso dequevarioscomponentesvayanatener el mismo comportamientoconeleventosera mejor emplearlaclaseinterna.Lasclasesinternasfuncionanbieninclusosielmanejadordeeventosnecesita accederaejemplaresdevariablesprivadasdelaclasequelaencierra.Siemprequenosedeclarelaclase internacomostatic,sepodrreferiraejemplaresdevariablesymtodoscomolohaceelrestodecdigoque contienelaclase.Parahacerqueunavariablelocalest disponibleparaunaclaseinternasolosetieneque haceruncopiadelavariablecomounavariablelocalfinal. Ejemplo: importjava.awt.event.*;//Seusaraneventos ... publicclassLeeTextoextendsFrame{ Listalista; JTextAreatexto; ... publicLeeTexto(){ ... texto.addActionListener(newIngresoDeTexto()); } ......... publicclassIngresoDeTextoimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ lista.add(texto.getText());//Agregaelitemalalista texto.setText("");//Borraelcampodetexto }}} Enelejemploloquesehaceesquecadavezqueseingresancaracteresenelcampodetexto,seagregaun temconlainformacinalalista.Lospuntoimportantesdelejemploson: IngresoDeTextoesunaclaseinternadelaclaseLeeTexto LaclaseinternavaasociadaaunobjetodelaclaseLeeTexto LaclaseinternatieneaccesoalasvariablesdeinstanciadelobjetoLeeTexto ActionListeneresunainterface Unainterfaceesunformarestringidadeclase(mtodossincdigo) Lasinterfacesnoseextienden,seimplementan

7.6.3Threadsyelmanejodeeventos
Elcdigodemanejodeeventosseejecutaenunslothread,elthreaddedespachodeeventos.Estoasegura quetodomanejadorde eventos se terminar deejecutarantes de ejecutar otro.Por ejemplo,elmtodo actionPerformeddelejemploanteriorseejecutaenelthreaddemanejodeeventos.Elcdigodedibujo tambinserealizaenelthreaddedespachodeeventos.Estosignificaquemientrasseest ejecutandoel mtodoactionPerformed,lainterfacegrficadelprogramaestar congelada,nosedibujar nadanise responder alaspulsacionesdelratn,porejemplo.Sisenecesitahacerunaoperacindelargaduracin comoresultadodeuneventodebehacerseenunnuevothread(odeotromodoenviandounapeticinaotro thread)pararealizarlaoperacin.

7.7Controladoresdedistribucin
Cada contenedor (Frame, Dialog, Panel, etc), tiene un controlador de distribucin (LayoutManager) de componentespordefectounobjetoqueimplementaelinterfaceLayoutManager.Sielcontroladorpor defectodeuncontenedornosatisfacelasnecesidadessepuedereemplazarfcilmenteporcualquierotro.El AWT suministra varios controladores de disposicin que van desde los ms sencillos (FlowLayout y GridLayout) a los de propsito general (BorderLayout y CardLayout) hasta los ms flexibles (GridBagLayout)yBoxLayout). LoscontroladoresdedistribucinseestablecenconelmtodosetLayout: voidsetLayout(LayoutManagermgr); Dependiendodelcontroladordedistribucin empleadorecibir diferentesparmetros.Por ejemplo,para establecerelcontroladordedistribucinFlowLayoutseharalosiguiente. jPanelXYZ.setLayout(newFlowLayout()); posteriormente,paraadicionarcomponentesseempleaelmtodoadd()delaclaseContainer,losprototipos delmtodoadd()sonlossiguientes. Componentadd(Componentcomp); Componentadd(Componentcomp,intindex); voidadd(Componentcomp,Objectconstraints,intindex); voidadd(Componentcomp,Objectconstraint); donde constraints son variables estticas propias de los controladores que sitan al componente adicionadoenciertaposicin.Estasvariablesdependendeltipodecontroladorempleado. Elordenenqueloscomponentesseagreguenalcontenedordeterminar suposicinendichocontenedor. Loscomponentesqueseagreguentambinpuedentenersuspropioscomponentesadicionadosaelconsu propiocontroladordedistribucin,esdecircuandounpanelrecibeaunoomaspanelesycadaunodeellos tienesuspropioscomponentes. BorderLayout BorderLayouteselcontroladordedistribucinpordefectoparatodaslasventanas,comoframesycuadrosde dilogo.Utilizacincoreasparacontenerloscomponentes:north,south,east,westycenter.Todoelespacio extrasesitaenelreacentral.Verfigura.

Figura7.7.1BorderLayout

Susconstructoresson: BorderLayout(); BorderLayout(inthor_gap,intver_gap);

Enestecaso,paraadicionarcomponentesauncontainerconestecontroladorseemplealasiguienteversin
7

delmtodoadd(). Componentadd(Componentcomp); voidadd(Componentcomp,Objectconstraints); dondelasconstraintspuedenserNORTH,SOUTH,EAST,WESTyCENTER.Ejemplo:


border_panel.setLayout(newBorderLayout()); ... border_panel.add(BorderLayout.NORTH,newJButton("Button1(NORTH)")); border_panel.add(BorderLayout.CENTER,newJButton("2(CENTER)")); border_panel.add(BorderLayout.WEST,newJButton("Button3(WEST)")); border_panel.add(BorderLayout.SOUTH,newJButton("LongNamedButton4(South)")); border_panel.add(BorderLayout.EAST,newJButton("Button5(EAST)"));

BoxLayout BoxLayout pone los componentes en filas o columnas. Respeta las peticiones de mximo tamao del componentepermitealinearlos.Verfigura.

Figura7.7.2BoxLayout boxlayout_panel.setLayout(newBoxLayout(boxlayout_panel,BoxLayout.Y_AXIS)); ... boxlayout_panel.add(newButton("Button1")); boxlayout_panel.add(newButton("2")); boxlayout_panel.add(newButton("Button3")); boxlayout_panel.add(newButton("LongNamedButton4")); boxlayout_panel.add(newButton("Button5"));

CardLayout CardLayoutpermiteimplementarun reacomnquepuedecontenerdiferentescomponentes(unoalavez). TabbedpanessoncomponentesSwingintermediariosquepropocionanunafuncionalidadsimilar,perocon unainterfacepredefinida.UnCardLayoutnormalmenteest controladorporun comboBox,elestadodel comboBoxdeterminaelpanel(grupodecomponentes)quemuestraelCardLayout.Verfigura.

Figura7.7.3CardLayout

publicclassCardLayoutDemoimplementsItemListener{ JPanelcards;//panelqueusaCardLayout finalstaticStringBUTTONPANEL="JPanelconJButtons"; finalstaticStringTEXTPANEL="JPanelconJTextField"; publicvoidaddComponentsToPane(Containerpane){ //PanelquecontendraalJComboBox JPanelcomboBoxPane=newJPanel();//usaFlowLayoutpordefecto 8

StringcomboBoxItems[]={BUTTONPANEL,TEXTPANEL};//elcontenidodelcombobox JComboBoxcb=newJComboBox(comboBoxItems); cb.setEditable(false); cb.addItemListener(this); comboBoxPane.add(cb); //Crealos"cards"panels(card1ycard2) JPanelcard1=newJPanel(); card1.add(newJButton("Button1")); card1.add(newJButton("Button2")); card1.add(newJButton("Button3")); JPanelcard2=newJPanel(); card2.add(newJTextField("TextField",20)); //Creaelpanelquecontendralos"cards"panels cards=newJPanel(newCardLayout());//estableceellayout cards.add(card1,BUTTONPANEL); cards.add(card2,TEXTPANEL); pane.add(comboBoxPane,BorderLayout.PAGE_START); pane.add(cards,BorderLayout.CENTER); } /** *Metodoquedeterminaquepanelactivar. *Cadacardpanelestarelacionadoconunacadenaqueeslaquelo"invoca" */ publicvoiditemStateChanged(ItemEventevt){ CardLayoutcl=(CardLayout)(cards.getLayout()); cl.show(cards,(String)evt.getItem()); }

FlowLayout FlowLayouteselcontroladorpordefectoparatodoslosPaneles.Simplementecolocaloscomponentesde izquierdaaderecha,empezandounanuevalneasiesnecesario.Verfigura.

Figura7.7.4FlowLayout

Susconstructoresson: FlowLayout(); FlowLayout(intalignment); FlowLayout(intalignment,inthor_gap,intver_gap); Ejemplo:


JPanelflow_panel=newJPanel(); flow_panel.setLayout(newFlowLayout());//yaespordefectoste ... flow_panel.add(newJButton("Button1")); flow_panel.add(newJButton("2")); flow_panel.add(newJButton("Button3")); flow_panel.add(newJButton("LongNamedButton4")); flow_panel.add(newJButton("Button5"));

GridLayout GridLayoutsimplementegeneraungrupodeComponentesquetienenelmismotamao,mostrndolosen unasucesindefilasycolumnas.Verfigura.

Figura7.7.5GridLayout

Susconstructoresson: GridLayout(); GridLayout(introws,intcolumns); GridLayout(introws,intcolumns,inthor_gap,intver_gap); Ejemplo:


JPanelgridlayout_panel=newJPanel(); ... gridlayout_panel.setLayout(newGridLayout(3,2)); gridlayout_panel.add(newJButton("Button1")); gridlayout_panel.add(newJButton("2")); gridlayout_panel.add(newJButton("Button3")); gridlayout_panel.add(newJButton("LongNamedButton4")); gridlayout_panel.add(newJButton("Button5"));

GridBagLayout GridBagLayout es el ms sofisticado y flexible controlador de distribucin. Alinea los componentes situndolosenunaparrilladeceldas,permitiendoquealgunoscomponentesocupenmsdeunacelda.Las filasdelaparrillanotienenporqueserdelamismaaltura;delamismaformalascolumnaspuedentener diferentesanchuras.Verfigura.

Figura7.7.6GridBagLayout

JPanelgridbaglayout_panel=newJPanel(); gridbaglayout_panel.setLayout(newGridBagLayout()); GridBagConstraintsconstraints=newGridBagConstraints(); //secreaunamallade3filas //sellenacadacuadrodelamallaconuncomponente //enlasdireccionesx,y constraints.fill=GridBagConstraints.BOTH;

10

//seestablecelamismaanchuraenladimensionvertical constraints.weighty=1.0; //lafilasuperiorincluira3componentes,cadauno //endiferenteslugaresapartirdelax0,0 //Boton0,0 constraints.weightx=1.0; constraints.gridx=0; constraints.gridy=0; gridbaglayout_panel.add(newJButton("0,0"),constraints); //Boton0,1 constraints.weightx=0.5; constraints.gridx=1; constraints.gridy=0; gridbaglayout_panel.add(newJButton("1,0"),constraints); //Boton0,2 constraints.weightx=0.1; constraints.gridx=2; constraints.gridy=0; gridbaglayout_panel.add(newJButton("2,0"),constraints); //lafiladeenmediotendra2componentes.Elprimerocomprendera //dosfilas,mientrasqueelsegundodoscolumnas //Elprimercomponentedelasegundafilaseextendera //hastalatercerafila //Boton0,1to0,2 constraints.weightx=1.0; constraints.gridx=0; constraints.gridy=1; constraints.gridheight=2; gridbaglayout_panel.add(newJButton("0,1to0,2"),constraints); //elsegundocomponentedelasegundalineaseextendera //horizontalmentehastalaterceracolumna //Boton1,1to2,1 constraints.weightx=1.0; constraints.gridx=1; constraints.gridy=1; constraints.gridheight=1; constraints.gridwidth=2; gridbaglayout_panel.add(newButton("1,1to2,1"),constraints); //laultimafilatendradoscomponentesconningunrelleno constraints.fill=GridBagConstraints.NONE; //Boton1,2 constraints.anchor=GridBagConstraints.SOUTHEAST; constraints.weightx=0.5; constraints.gridx=1; constraints.gridy=2; constraints.gridheight=1; constraints.gridwidth=1; gridbaglayout_panel.add(newJButton("1,2"),constraints); //Boton2,2 constraints.anchor=GridBagConstraints.WEST; constraints.weightx=0.1; constraints.gridx=2; constraints.gridy=2; constraints.gridheight=1; constraints.gridwidth=1; gridbaglayout_panel.add(newJButton("2,2"),constraints);
11

OtrosLayouts Existenotroscontroladoresdedistribucinpropocionadosporlosentornosdedesarrollo(terceraspartes)y sonpropiosdeellosmismos,esdecir,nosonpartedelJDKyportantoparasuusodebeconsiderarse importarlasclasesapropiadas.Algunossonlossiguientes:


ALE AlignLayout DiagonalLayout EasyLay FlexGridLayout FractionalLayout GroupLayout LogFontLayout HtmlLayout MJTPacker MosaicLayout PackerLayout PercentLayout PnutsLayout PositionLayout ProportionalLayout RelativeLayout RiverLayout SplitterLayout StackLayout StretchyLayout TableLayout TreeLayout VFlowLayout XmFormLayout XyLayout

8.JDBC JDBCeselAPIdeJavaparacomunicarsemediantesentenciasSQLconbasesdedatos.JDBCespartedelas JavaEnterpriseAPI's.Acontinuacinsedescribirnlosaspecotsbsicosrelativosaestetema. SQLesunlenguajeparacrear,manipular,examinaryadministrarbasesdedatosrelacionales.YaqueSQLes unlenguajeespecficoparauntipodeaplicacin,unasolasentenciaSQLpuedesermuyexpresivaypuede iniciaraccionesdealtonivel,talescomomezclaruordenardatos.SQLfueestandarizadoen1992paraque un programa pudiera comunicarse con la mayora de los sistemas de bases de datos sin que debieran cambiarse/personalizarselassentenciasSQL.Desafortunadamentecadavendedordesistemasdebasesde datosestablecesuspropiasinterfaces(variantesdeSQL)paracomunicarseconsusproductos.Esaqudonde entraODBC(OpenDatabaseConnectivity). ODBCesunainterfacebasadaenCparamotoresdebasesdedatosqueproporcionaunainterfaceparala comunicacinconbasesdedatosyparaaccederametadatos(informacinrelativaalvendedordelsistema debasededatos,cmoseguardanlosdatos,etc.).Cadavendedorproporcionasuspropioscontroladores (drivers)paraestablecerunpuenteasusistemadebasededatos.Enconsecuencia,graciasalODBCySQL seunosepuedeconectarymanipularunabasededatosdemaneraestandarizada.ODBChallegadoaserun estndarindustrial. Aunque SQLesadecuadoparamanipularbasesdedatos,noesunlenguajedeaplicacingeneral.Los programadoresloempleanprincipalmentecomomediodecomunicacinconbasesdedatos,perotambin empleandootrolenguajeparaintroducirlassentenciasSQLalabasededatosyprocesarvisualmentela informacinextrada.Desafortunadamente,anconODBC,noesposiblecrearaplicacionesmultiplataforma conbasesdedatos.EsaqucuandoentraJDBC(JavaDatabaseConnectivity). JDBCformapartedelconjuntodelibrerasdeJava(formapartedelJDK).EsunaversinJavadelODBC. ActualmentemuchosvendedoresdesistemasdebasededatosproporcionanloscontroladoresJDBCdesus productos.SunasuvezhacreadopuentesparatraducirJDBCaODBCparapermitirlacomunicacincon sistemasdebasesdedatoslegadosquenofuerondesarrolladosparainteractuarconJava.Elcontrolador JDBCODBCesunodelostiposdecontroladoresdisponiblesparasoportarlaconectividadJDBC.Lostipos sonlossiguientes:

12

Categora JDBCODBC APInativobase JDBCNet Protocolonativobase

Javapuro No No ClienteSi ServidorPuedeser Si

Conexinared Directa Directa Indirecta Directa

8.1Creacindeunatabladeunabasededatos OperarconJDBCparaconectarseaunabasededatosesrelativamentesencillo.Losaspectosrelacionados conunaaplicacindeestetiposon: 1. Crearunabasededatos.EstopuedehacersemedianteunprogramaJava,conotrotipodeaplicacin oconelmismosistemadebasededatos. 2. Conectarseconlabasededatos.EstoseharconelJDBCqueproporcionaelvendedordelsistema debasededatos. 3. Insertarinformacinalabasededatos.Estotambinpuedehacerdelamismamaneraqueelpunto 1. 4. Recuperarinformacin.ParaelloseempleansentenciasSQLdesdeelprogramaJavaelcualtambin desplegarymanipularlosdatosextrados. Crearlabasededatos Considreseelcasodequesedeseaguardarenlabasededatoslacantidaddetazasdecaf conconsumen ciertoprogramadoresalda: Programador

Da

Lun Rosa Lun Pedro Mar Rosa Mar Edgar Mar Maurici Mie o Edgar Jue Gilberto Jue Eugenia Vie Pedro Vie Maurici Vie
Gilberto

# tasas 1 2 8 2 3 2 3 1 9 3 4
13

o
Paraintroducirestosdatosenlabasededatosdebenseguirselossiquientespasos:

1. CargarelcontroladorJDBCODBCmediantelaclaseJdbcOdbcDriver:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); tambinpuedehacersedesdelalneadecomandos: javaDjdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriverAProgram

2. Conectarsealabasededatos,paraestoseempleaunURLquedebeestardelasiguientemanera

jdbc:odbc:datasourcename.MediantelaclaseDriverManagersesolicitalaconexin alURL,DriverManagerseleccionaelcontroladorapropiado;enestecasosoloelcontrolador JdbcOdbcDriversecarga.

Connectioncon=DriverManager.getConnection( URL, usuario, password); dondeusuarioypasswordpertenecenaquienseestconectando.

3. Enviar sentencias SQL para crear la tabla, para ello se pide un objeto conexin para el objeto
Statement: Statementstmt=con.createStatement(); As,seejecutalasiguientesentenciaparacrearlatablaCafeteros.
createtableCafeteros( programadorvarchar(32), diachar(3), tazasinteger);

Elcdigoquehaceesoeselsiguiente:
stmt.execute("createtableCafeteros("+ "programadorvarchar(32),"+ "diachar(3),"+ "tazasinteger);" );

Unavezcreadalatablayasepuedeninsertarlosvaloresapropiados,talescomo: insertintoCafeterosvalues('Gilberto','Lun',1); insertintoCafeterosvalues('Rosa','Lun',2); insertintoCafeterosvalues('Pedro','Mar',8); ... Elcdigocompletoeselsiguiente:


importjava.sql.*;//importalltheJDBCclasses 14

publicclassCreateCafeterosDB{ staticString[]SQL={ "createtableCafeteros("+ "programadorvarchar(32),"+ "diavarchar(3),"+ "tazasinteger)", "insertintoCafeterosvalues('Gilberto','Lun',1)", "insertintoCafeterosvalues('Rosa','Lun',2)", "insertintoCafeterosvalues('Pedro','Mar',8)", "insertintoCafeterosvalues('Rosa','Mar',2)", "insertintoCafeterosvalues('Edgar','Mar',3)", "insertintoCafeterosvalues('Mauricio','Mie',2)", "insertintoCafeterosvalues('Brenda','Jue',3)", "insertintoCafeterosvalues('Gilberto','Jue',1)", "insertintoCafeterosvalues('Eugenia','Vie',9)", "insertintoCafeterosvalues('Pedro','Vie',3)", "insertintoCafeterosvalues('Mauricio','Vie',4)" }; publicmanipulaDB(){ //StringURL="jdbc:odbc:Cafeteros"; StringURL="jdbc:mysql:ubicacionCualquiera"; Stringusername="username"; Stringpassword="password"; try{ Class.forName("mysql.jdbc.driver.MySQLDriver"); }catch(Exceptione){ System.out.println("FalloalcargarelcontroladorJDBC/ODBC"); return; } Statementstmt=null; Connectioncon=null; try{ con=DriverManager.getConnection( URL, username, password); stmt=con.createStatement(); }catch(Exceptione){ System.err.println("problemasalconectarcon"+URL); } try{ //ejecuteloscomandosSQLparacreartablaeinsertardatos for(inti=0;i<SQL.length;i++){ stmt.execute(SQL[i]); } System.out.println("hecho"); con.close(); }catch(Exceptione){ System.err.println("problemasconlasentenciaSQLenviadaa"+URL+ ":"+e.getMessage()); } } }//class

8.2Extraccindeinformacindeunatabla
Para recuperara datos de una base de datos se emplean sentencias SQL select mediante el mtodo Statement.executeQuery,elcualretornalasfilasdela(s) tabla(s)enunobjeto ResultSet.Los
15

resultados se pueden examinar fila a fila por medio de los mtodos ResultSet.next y ResultSet.getXYZ. Siguiendoconelejemplodeloscafeteros,considresequesedeseasaberlacantidadmximadetazasde caf consumidasporlosprogramadoresenunda.EntrminosdeSQL,estosepodralograrordenandola tabla por la columna tazas en orden descendente. As slo se selecciona el nombre del programador relacionadoconcadavaloryseimprime: SELECTprogramador,tazasFROMCafeterosORDERBYtazasDESC; EnJavaestosera: ResultSetresult=stmt.executeQuery("SELECTprogramador,tazasFROM CafeterosORDERBYtazasDESC;"); LacolumnatazasdelprimerrenglndelResultSettendrelmximonmerodetazas:

Eugeni a Pedro Mauric io Pedro Edgar Edgar Rosa Rosa Mauric io


Gilberto Gilberto

9 8 4 3 3 3 2 2 2 1 1

LamanipulacindelResultSetpuedehacersedelasiguientemanera. visitarregistros: result.next(); extraerdatosdelascolumnasdeunregistro: Stringnombre=result.getString("programador"); inttazas=result.getInt("tazas");

16

imprimirlainformacin: System.out.println("elprogramador"+nombre+"consumiomascafe: "+tazas+"tazas"); queresultaren: elprogramadorEugeniaconsumiomascafe:9tazas Considreseahoracalculareltotaldeventasdetazasdecaf portodoslosprogramadores.Paraellose vuelvealacolumnatazasyseemplealasentenciaselectdelasiguientemanera: result=stmt.executeQuery("SELECTcupsFROMCafeteros;"); losdatosserecorrenmedianteelmtodonexthastaqueretornefalse,loqueindicaquenohaymsregistros: //recorrecadafila cups=0; while(result.next()){ tazas+=result.getInt("tazas"); } Elclculoseimprimedelasiguientemanera: System.out.println("ventastotalesde"+tazas+"tazasdecafe"); queimprimir ventastotalesde38tazasdecafe elcdigocompletoparaexaminarlatablaCafeterosygenerarelreportesepuededescargardelapginade laasignatura.

8.3ConectarunprogramaJavaconunabasededatos
ActualmenteexistendosmanerasdeconectarunprogramaJavaaunabasededatos.Laprimeraesobtenerel controladorJDBCdelabasededatos.LasegundamaneraesemplearelcontroladorJDBCODBCque proporcionaJavasoft,realmenteeslaclaseJdbcOdbcDriver.Unavezestablecidalaformadeconexin, se abrir la conexin a la base de datos a travs de un objeto Connection obtenido va DriverManager.getConnection,elcualseleccionaeldriverapropiadoparalacomunicacinconla basededatos.TodaslasfuentesdedatosODBCseidentificanvaunURLdelasiguientemanera: jdbc:odbc:datasourcename Elmtodo getConnectionretornaunConnectiondelafuenteespecificadamedianteelcontrolador JDBCODBC.Porejemplo,paraconectarsealafuenteODBCllamadacursopooconelusuarioalumno ypasswordalumnopooseharaalgocomolosiguiente: //cargaelcontroladorJDBCODBC try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }catch(Exceptione){ System.out.println("FalloencargadelcontroladorJDBC/ODBC");
17

return; } //obtienelaconexion try{ con=DriverManager.getConnection( "jdbc:odbc:cursopoo", "alumno", "alumnopoo"); }catch(Exceptione){ System.err.println("problemasparaconectara"+URL); } UnavezestablecidalaconexinyasepuedenenviarsentenciasSQL.

8.4Lacomunicacinconunabasededatos
Si ya se tiene establecida la conexin con la base de datos de podrn ejecutar sentencias SQL para la manipulacindelabasededatos.Pormediodelmtodo Connection.createStatementseobtiene unobjetoStatementyassepuedenejecutarlosmtodosexecuteQueryoexecuteUpdate.JDBC noponeningunarestriccinalassentenciasSQLquesedeseenejecutarmediantelosmtodosexecute, pero se debe asegurar que la base de datos soporta tales sentencias. Para que una base de datos sea compatibleconJDBCdebesoportaralmenoslascaractersticasSQL2EntryLevel.

8.5Actualizacindeunabasededatos Supngase que con es una referencia a un objeto Connection obtenido mediante el mtodo DriverManager.getConnection, as se pueden enviar sentencias SQL de actualizacin
(INSERT,UPDATEoDELETE)alabasededatospormediodeunobjeto Statementyluegoinvocando elmtodoexecuteUpdate.Porejemplo,paracrearunatablaDataconunregistroseharalosiguiente: Statementstmt=con.createStatement(); //crearlatablaconlascolumnasnombreypeso stmt.executeUpdate( "createtableData(nombrevarchar(32),pesointeger);"); stmt.executeUpdate( "insertintoDatavalues('Ximena',52);"); con.close(); //cerrarlaconexion,commitlatransaccion ElmtodoexecuteUpdateretornaelnmeroderegistrosafectadosoceroparaaquellassentenciasSQLque nadaretornan.

8.6Consultasaunabasededatos
Paraconsultarunabasededatos(mediantelaSELECT)seempleaelmtodo executeQuery,elcual retornaunobjeto ResultSet.Elobjeto ResultSet nuncaser null ycontienelosregistrosdela consultaSQL.Porejemplo,conelsiguientecdigoseseleccionandoscolumnasdedatosdesdelatabla llamadaDataenordenascendentesegnelpeso. ResultSetresult=stmt.executeQuery( "SELECTnombre,pesoFROMDataORDERBYpesoASC;"); Las filas resultantes se acceden en orden, pero los elementos de varias columnas pueden accederse en cualquierorden.Paramayorportabilidadentrebasesdedatos,JavaSoftrecomiendaquelascolumnassean
18

accedidasenordendeizquierdaaderechayslounafilapuedeleersealavez.Existeunrowcursorenel resultadodelasentenciaSQLqueapuntaalafilaactual.ElmtodoResult.nextmueveelcursorfilaa fila.Antesdeleercadafilaesnecesariollamaralmtodo nextparainicializarelcursosalaprimerfila.El siguienteejemplomuestracmoleerlasprimerasdosfilasdedatosylasimprime. Stringnombre; intpeso; if(result.next()){//muevealaprimerafila nombre=result.getString("nombre"); peso=result.getInt("peso"); System.out.println(nombre+":"+peso); } if(result.next()){//accedealasegundafila nombre=result.getString("nombre"); peso=result.getInt("peso"); System.out.println(nombre+":"+peso); } Elmtodonextretornafalsecuandoyanoexistefilaalguna. Sedebetenerencuentaquelosnombresdelascolumnassoncasesensitiveyquesiexistendosomas columnasconelmismonombresoloseaccedealaprimera.Cuandoseaposiblesedebeemplearelndicede lacolumna.SepuedepreguntaralobjetoResultSetelndicedecualquiercolumnasinosesabe. indexNomCol=result.findColumn("nombre"); indexPesoCol=result.findColumn("peso"); La informacin de las propiedades de una columna ResultSet la proporciona la clase ResultSetMetaDataylaretornamedianteelmtodoResultSet.getMetaData.Verlaseccinde metadatos.

8.7Sentenciaspreparadas
Cuandoseejecutalamismaoperacinvariasvecesesmejoremplearunasentenciapreparada(nosonlos procedimientos de la base de datos) para mejor eficiencia en tiempo de ejecucin, lo que cual es precompiladoporelmotorSQL(asumiendoquelabasededatoslosoporta).Lassentenciaspreparadas tambinsontilescuandosedebenespecificarvariosargumentosenunasentenciaSQLparticular. Lassentenciaspreparadassonunaextensindeunobjeto Statement yconsecuentementesecomporta como un Statement con la excepcin de que deben crearse con mtodo Connection.prepareStatement en lugar del mtodo Connection.createStatement, tal comosemuestraacontinuacin:
PreparedStatementprep=con.prepareStatement("INSERTintoDatavalues(?,?)");

LosargumentosIN(indicadoscon '?')puedenrellenarseconlosmtodosetXYZ.Debeasegurarsequeel parmetro(indicadoconelnmerode ndiceempiezaen1)queseestablecedebecoincidirconeltipode datoqueseestpasando.Porejemplo,paralatablaDatacondoscolumnas,connombredetipocharypeso detipointeger,losparmetrosdelobjetoPreparedStatementpuedenestablecersemedianteelsiguiente cdigo: prep.setString(1,"Julian"); prep.setInt(2,70);


19

As para ejecutar la sentencia preparada con los parmetros establecidos se hace mediante el mtodo executeUpdate: if(prep.executeUpdate()!=1){ thrownewException("BadUpdate"); }

8.8Metadatos
Se puede acceder a la informacin de la base de datos como un todo o slo mediante una consulta ResultSet.Enestaseccinsedescribecmoseobtienenmetadatosdelabasededatosconlosobjetos DatabaseMetaDatayResultSetMetaData. Cuandosedeseaconocerlainformacinsobrelabasededatos,porejemplocapacidades,vendedor,etc.,se lepreguntaalobjetoConnectionporesosmetadatos.Estosehacedelasiguientemanera: Connectioncon=DriverManager.getConnection( "jdbc:odbc:mydatasource","usuario","password"); DatabaseMetaDatamd=con.getMetaData(); Sepuedenpreguntarmuchascosas,porejemplo,elsiguientefragmentodecdigopreguntaalabasede datossunombreycuntasconexionessimultneassoporta. if(md==null){ System.out.println("BasededatossinMetadatos"); }else{ System.out.println("NombredeBasededatos:"+ md.getDatabaseProductName()); System.out.println("#conexionesactivas:"+ md.getMaxConnections()); } Paraconocerelnmeroytiposdelascolumnasseempleaelobjeto ResultSet obtenindoleelobjeto ResultSetMetaData.Porejemplo: ResultSetresult=...; ResultSetMetaDatameta=result.getMetaData(); intnumbers=0; intcolumnas=meta.getColumnCount(); System.out.println("Columnas:"+columnas); Porejemplo,volviendoalejemplodeloscafeteros,paradeterminarelnmeroytipodelascolumnasque retornalasiguienteconsultaSQL: SELECTprogramador,tazasFROMCafeterosORDERBYtazasDESC; seinvocaalmtodoexecutedelasiguientemanera: ResultSetresult=stmt.executeQuery( "SELECTprogramador,tazasFROMCafeterosORDERBYtazasDESC;");

20

luegoseobtienenlacolumnaytipodemetadatodelResultSet: ResultSetMetaDatameta=result.getMetaData(); as,sepuedeconsultarelResultSetMetaDataparadeterminarcuntascolumnashay: intcolumns=meta.getColumnCount(); sepuederecorrerlalistadecolumnasimprimiendosusnombresytiposdedatos: intnumbers=0; for(inti=1;i<=columns;i++){ System.out.println(meta.getColumnLabel(i)+"\t" +meta.getColumnTypeName(i)); if(meta.isSigned(i)){//esunnumeroconsigno? numbers++; } } System.out.println("Columnas:"+columnas+"numericas:"+ numbers); Laaplicacincompletapuededescargarsedelapginadelaasignatura.

8.9Transacciones
Unatransaccinesunconjuntodesentenciasquehansidoejecutadasyllevadasacabo(commit)o roller back.Parahacerelcommitdeunatransaccinseinvocaalmtodo commit enlaconexinapropiada,se emplearollbackparadescartarloscambioshechosconel ltimocommit.Pordefectotodaslasconexiones nuevassonenmodoautocommit,loquesignificaquecadaexecuteesunatransaccincompleta.Seinvoca Connection.setAutoCommitparacambiarlaopcinpordefecto.Cualquierbloqueo(lock)deunatransaccin seliberadespusdelaejecucindelmtodocommit. Connectioncon=DriverManager.getConnection(...); con.setAutoCommit(false); Statements=con.createStatement(); s.executeUpdate("SQLstatement1"); s.executeUpdate("SQLstatement2"); s.executeUpdate("SQLstatement3"); con.commit(); //comitdelas3transaciones Todos los controladores JDBC soportan transacciones. Es necesario verificar el DatabaseMetaData asociadoconlaconexinparadeterminarelnivelsoportadodetransaccionesqueproporcionalabasede datos.

8.10Procedimientosentablas
UnprocedimientodetablaesunbloquedecdigoSQLalmacenadoenlabasededatosyejecutadoenel servidor. La interface CallableStatement permite interactuar con ellos. El manejo de objetos CallableStatement es similar a los objetos PreparedStatement. Los procedimientos tienen parmetrosypuedenretornaryaseaunResultSetouncontadordeactualizacin.Susparmetrospueden serdeentradaosalida.LosparmetrosdeentradaseestablecenmediantemtodossetXYZ.Losparmetros desalidasedebenregistrarmedianteelmtodoCallableStatement.registerOutParamter.Los procedimientos deben ser soportados por la base de datos para poder usarlos; esto se puede saber
21

preguntandoaunobjetoDatabaseMetaDatamedianteelmtodosupportsStoredProcedures. Considerandoelejemplodeloscafeterossepuedevercmosellevaacaboesto.Considresequeenlugarde querersabereltotaldeventasdelasemana,eladministradorquierelaventatotaldeundaparticular.Para estosepuedecrearunprocedimiento,esteprocedimientorealmentelodebecreareladministradordelabase dedatosynolosprogramadoresdelasaplicaciones.Suponiendoqueeladministradordelabasededatos haceelprocedimiento,elusuariononecesitasabercmotrabajasinoquenicamenteloinvocaylisto. Suponiendoqueseeseladministradordelabasededatos,secrear elprocedimiento.Comocualquierotra sentenciaSQL,senecesitaunobjetoConnectionyunStatement. Statementstmt=con.createStatement(); AsseejecutalasiguientesentenciaSQL: CREATEPROCEDUREgetVentasDiariasTotales @daychar(3),@dayTotalintoutput AS BEGIN SELECT@dayTotal=sum(tazas) FROMCafeteros WHEREdia=@day END ElcdigoJavaeselsiguiente: stmt.execute("CREATEPROCEDUREgetVentasDiariasTotales"+ "@daychar(3),@dayTotalintoutput"+ "AS"+ "BEGIN"+ "SELECT@dayTotal=sum(tazas)"+ "FROMCafeteros"+ "WHEREdia=@day"+ "END" ); Unavezquehasidoelprocedimientohacreado,sepuedeinvocarconunCallableStatement: CallableStatementcstmt=con.prepareCall("{call getVentasDiariasTotales(?,?)}"); cstmt.setString(1,"Lunes"); cstmt.registerOutParameter(2,java.sql.Types.INTEGER); cstmt.executeUpdate(); System.out.println("Eltotales"+cstmt.getInt(2)); Lasintaxisexactaparacrearyalmacenarelprocedimientopuedevariardependiendodelabasededatos. Asimismo, si no hay parmetros de salida para el procedimiento se puede emplear un objeto PreparedStatement.SinohayparmetrosdeentradaosalidasepuedeusarunobjetoStatement.

8.11EquivalenciadetiposentreJavaySQL
ParacadamtodogetXYZelcontroladorJDBCdebeconvertireltipodedatosentrelabasededatosyJava. Elcontroladornopermiteejecutarconversionesdedatosinvlidas(porejemplo,unStringauninteger),pero
22

permiteobtenertodocomounString.Lasconversionescomunesson: mtodoJava getInt getLong getFloat getDouble getBignum getBoolean getString getString getDate getTime getTimestamp getObject tipoSQL INTEGER BIGINT REAL FLOAT DECIMAL BIT VARCHAR CHAR DATE TIME TIMESTAMP cualquirtipo

Porejemplo,dadounobjetoResultSetquecontienefilasdenombresyfechas,sepuedenusargetStringy getDateparaextraerinformacin:
ResultSetresult=stmt.executeQuery("SELECTnombre,diaFROM..."); result.next(); Stringname1=result.getString("name"); DatewhatDay1=result.getDate("dia");

8.12ExcepcionesJDBC
JDBCproporcionatrestiposdeexcepciones: SQLException SQLWarning DataTruncation SQLExceptions LaSQLExceptioneslabasedetodaslasexcepcionesJDBC.Consistedetrespiezasdeinformacin,un mensaje String, como las hijas de Exception, otro String con el estado SQL XOPEN y un entero especficodeldriver/basededatoscomocdigodeerror.Mltiplesinstanciasde SQLExceptionpueden encadenarse. SQLWarnings LaclaseSQLWarningessimilaralaSQLException,soloquenoseconsideraunerrorcrticoynoes disparada. El programador debe controlar (atrapar) los mensajes SQLWarning mediante los mtodos getWarningsdeConnection,ResultSetyStatement.Sinosecontrolan(atrapan)nosereciben pordefecto.CadavezquesehacealgoconunConnection,ResultSetyStatementseeliminan loswarningsprevios. DataTruncation La clase DataTruncation es un tipo especial de SQLWarning. Se reporta con otras instancias de SQLWarning eindicacundosehaperdidolainformacinduranteunaoperacindelecturaoescritura. Para detectar un truncamiento es necesario ejecutar una verificacin con una instancia de DataTruncationencadaSQLWarningdesdeelencadenamientogetWarnings.

23

8.13CumplimientoSQL
AunqueSQLesunestndar,notodosloscontroladoresJDBCcumplentotalmentelagramticaANSI92. Estosepuedesaberpreguntandoalobjeto DatabaseMetaData. DatabaseMetaData contienetres mtodosquereportanelniveldegramticassoportadoporelcontrolador: supportsANSI92EntryLevelSQL.TodosloscontroladoresJDBCdebenretornartrue supportsANSI92IntermediateSQL supportsANSI92FullSQL EnadicinalosmltiplesnivelesdeANSI92soportadosporloscontroladoresJDBC,hayvariosnivelesde soporteSQLparalasfuentesODBC.Tambinsepuedendeterminarestosniveles.DatabaseMetaData contienetresmtodosquereportanelniveldegramticassoportadoporlabasededatos: supportsMinimumSQLGrammar supportsCoreSQLGrammar supportsExtendedSQLGrammar Estosnivelesdeterminanqu operacionesSQLespecficasoqu opcionesdeestasoperacionessepueden ejecutar. CuandoseempleaunpuenteJDBCOSBC,elcontroladorODBCpuedeademsrestringirlascapacidades; porejemplo,nosepuedenusarsentenciaspreparadasconelcontroladorODBCparaarchivosdetexto. Conbaseenlosnivelesdisponibles,puedeserbenficoproporcionarrutasalternativasdeejecucinpara ciertas operaciones. Por ejemplo, cuando se pobla una tabla con valores de otra table, el ncleo de la gramticaSQLpermiteunaclusulaSELECTcomopartedeunaclusulaINSERT.Estoesmuchoms rpidoqueejecutaruncicloselectconuninsertporcadaregistro,loscualesnecesariosiseestempleando unagramticaSQLmnima.

9.JavaBeans
JavaBeans brinda a Java las caractersticas de los llamados componentes desde un punto de vista de programacinengeneral.ConelAPIdeJavaBeanssepuedencrearcomponentestotalmentereusablese independientes de la plataforma. Siguiendo los lineamientos para la construccin de componentes JavaBean, estos componentes se pueden emplear en applets, aplicaciones y otros componentes. A los componentesJavaBeansselesllamaBeans.

9.1Definicindecomponente
De manera general se dice que un componente es una parte de un todo, de forma que esa parte es independiente.Desdeelpuntodevistadeprogramacinloscomponentessonpequeostrozosdesoftware, algoritmos,etc.deformaquesonindependientesentresi,ytodoscolaborandoentreellosejecutanunatarea. Lossistemasdesoftwareactualesyanosonmonolticos(dondetodoelproyectodesoftwareerauntodo). Actualmenteunproyectodesoftwaresefragmentaenpartes,lascualessedesarrollabanindependientesy luegoseunenenunosolo(manteniendoesaspartesdeformadiferenciada). Porejemplo,cuandosedesarrollaunproyectoconinterfazgrficaysedeseainsertarunbotn,esebotnya esunaporcindesoftwarequeproporcionar ellenguajeoquehasidocreadodemanerapersonalizada.El botntendr: unaseriedecaractersticascomocolor,tamao,texto,nombre,etc.Unaseriedemtodosy
24

unaseriedeeventosasociados.

Manualmentesepuedeescribirelbotneinsertarloenelproyecto,perofacilitandomslascosas,sepodra pensarenqueseramejorqueexisteseunaaplicacinconlacualsepuedaintroducirelbotndirectamenteal proyecto.Estofacilitaramucholalabordelprogramador.TaleselcasedelosIDE'sEclipse,JBuildery NetBeans, tambin llamados herramientas RAD (Rapid Aidded Design). Estos IDE's son herramientas automticasconlascualessepuedenintroducirbotones(porejemplo),arrastrandoelelementodesdeuna paneldelamismaherramienta,ynosloeso,sinoqueesasherramientassoncapacesdemostrar: laspropiedadesdelbotninsertadoparamodificarlaspropiedadesdedichobotnentiempode edicin losmtodosdelbotn loseventosquetieneasociadosesebotnauneventodetecladooderatn Aquentraenjuegolalabordeloscomponentes,loscualesdanunaideadecmodiferenciaruncomponente deunaclaseenjava.Uncomponenteesunaunidadmsabstractaqueunobjeto,yaqueademsdelcdigo encapsula informacin acerca de l. Estos componentes encapsulan informacin acerca de sus mtodos, eventos,propiedades,conloqueunaherramientaRADpodrrecogeresainformacinymostrarlaalusuario (programador)paraayudarasteamodificarpropiedades,eventosymtodos. Loscomponentessonindependientes,sepuedencomunicarentres,sepuedemostrarsuinformacinde formaquepuedanserintroducidosdeformarpidayeficienteenunproyecto.Estaeslagranventajayaque en poco tiempo y usando estas piezas de software se puede desarrollar software de forma rpida. Los componentespuedensergrficosono.Porejemplopuedehabercomponentesparadesarrollaralgoritmoso ventanasybotones.Unavezdesarrolladospuedeninsertarseyresultilizarsedondeycuandosedesee.

9.2JavaBeans
LenguajescomoVisualBasic,VisualFoxProyDelphisonlenguajesquepermitenmanejarcomponentes. JavaBeans es la aportacin de Java a los componentes. Con el API de JavaBeans se pueden crear componentes totalmente reusables e independientes de la plataforma, los cuales se pueden emplear en applets,aplicacionesyotroscomponentes.AloscomponentesJavaBeansselesllamaBeans. UnadelasmayoresventajasqueaadeJavaessucompatibilidadconcualquierplataforma.JavaBeansest preparado y aade funcionalidades para que se puedan crear y manipular componentes mediante herramientasgrficas,porejemploEclipse,Jbuilder,NetBeansyBeansBuilder,lascualespermitenemplear loscomponentesquelaaplicacinyaproporciona(botones,areasdetexto,barrasdedesplazamiento,...)y crearcomponentescomplejos(comolaagregacindecomponentessimplesolaagregacindecomplejos). LosJavaBeans,enapariencia,sonclasesjava.Elcdigoesvisualmenteigualysecompilandelmismo modo.PeroJavaBeansvaams,loquerealmentedistingueunBeandeunaclasesesquelosBeansestn pensadoscomoherramientasdecomposicin.DeestaformasefacilitalacomposicindenuevosBeans mediantelaagregacindecomponentesoagregarcomponentesalasaplicacionesadesarrollardemanera intuitiva(almenosdemaneravisual).Paraelloseempleaelparadigmadelamanipulacindirecta,con accionestansimplescomoseleccionar,arrastrarysoltar(drag&drop). JavaBeanssepuedecompararconlatecnologaActiveX.ActiveXseempleaparacrearlamayoradelos componentesanlogosalosJavaBeansenplataformasWindows.Cabehacernotarlossiguientesaspectos: JavaBeansesunframeworkparaconstruiraplicacionesJavaconBeans. ActiveXesunframeworkparadesarrollarcomponentesconcontrolesActiveX. Un Bean es similar a un control ActiveX, pero claro escrito en Java y con la ventaja de que implementaaspectosdeseguridadJavayesindependientedelaplataforma. EsposibleimplementarcontrolesActiveXmedianteJava,peroestorequiereunpuertodelModelode
25

Objetos Comunes (Common Object Model COM) de Microsoft para que pueda emplearse en aplicacionesnoMicrosoft. LamayoradeloscontrolesActiveXhansidocreadosmedianteVisualBasicoVisualC++yse compilanconlibrerasnativasdelsistemaoperativo.

9.2.1Conceptos
AcontinuacinsepresentanlosconceptosrelacionadosconBeans: Unaherramientadedesarrollo(IDEcapazdemanejarBeans)descubrelascaractersticasdelBean (propiedades,mtodosyeventos)pormediodeunprocesodenominadointrospeccin.LosBeans soportanlainstrospeccindedosmaneras: Agregandocomopartedes mismosreglasespecficas,conocidascomopatronesdediseo, cuandosenombranlascaractersticasdelBean.LaclaseIntrospector(java.beans.Introspector) examinalosBeansdeterminarlospatronesdediseoydescubrirlascaractersticasdelBean. Explcitamenteproporcionandoinformacindelosatributos,mtodosyeventospormediode unaclase BeanInformation relacionada.UnaclaseBeanInformationimplementalainterface BeanInfo,lacualexplcitamentelistalascaractersticasdelBeanparaqueseanexpuestasala herramientadedesarrollo. Las propiedades son la apariencia del Bean y sus caractersticas de comportamiento, las cuales pueden cambiarse en tiempo de diseo. La herramienta de desarrollo examina un Bean para descubrirsuscaractersticasyhacerlasdisponibles. Los Beans exponen sus propiedades para que pueden personalizarse en tiempo de diseo. La personalizacinpuedeserdedosmaneras:Pormediodeuneditordepropiedadesorpormediode personalizadoressofisticados. LacaratersticadepersistenciapermitequeunBeanpuedaguardaryrecuperarsusestado.Unavez que se han cambiado las caractersticas de un Bean, este estado puede guardarse y recuperarse posteriormente con las propiedades intactas. JavaBeans emplea la serializacin de objetos para soportarlapersistencia. LosmtodosdeunBeansoncomocualquiermtododeunobjetoJavacomnypuedeninvocarse desdeotrosBeansoambientedescripts.Pordefectoseexportantodoslosmtodospblicos. Demanerageneral,laarquitecturabsicadeunBeanconsisteenexportarohacerdisponibles: Propiedades:lascosasquedescribenloqueunBeanes Mtodos:lascosasqueunBeanpuedehacer Eventos:lasaccionesqueunBeanpuedegeneraryresponder. Un Bean debe respetar el API de JavaBeans (http://java.sun.com/j2se/1.5.0/docs/api/java/ beans/package summary.html)

9.2.2Propiedades
UnBeanposeelassiguientespropiedades: Introspeccin:EstemecanismopermiteanalizarelfuncionamientointernodeunBeanobteniendodellos mtodos,propiedadesyeventos.Deestamaneraunaherramientavisual puedemostrarlaspropiedades, eventos y mtodos cuando, por ejemplo, se selecciona y arrastra un componente. Un Bean puede considerarsecomounacajanegra,deformaqueparaqueunaherramientaautomticacomoNetBeanspueda obtenerdeesacajasusmtodos,propiedadesyeventos,paramostrrselasalusuarioystemanipularlaspara supersonalizacinoparaqueinteracteconotrosBeans,seledebedeproporcionardealgunafacilidad.Con estefinsedefinelaintrospeccin.Paraello,eldiseadordelBeanpodradefinirun BeanInfoasociadoal Bean y que la herramienta obtuviera del BeanInfo los datos necesarios del Bean, esto se logra
26

implementandolainterfazBeanInfopara ese botn.Se implementan los mtodosquesedeseendeese BeanInfoylosnodeseadosdebendevolvernull.EnloscasosqueelBeanInfonoexisteosusmtodos devuelvennullserecurrealaintrospeccin.EsaclaseproveelosmtodosparaquesecreeunBeanInfo asociadoaeseBean.ParaellorecurreaBeanInfosasociadosaesaclaseoasussuperclasesycreaun BeanInfodedondesepuedaobtenerinformacindelosmtodos,propiedadesyeventosdeeseBean.Sino dispone de otro Bean de donde obtener la informacin necesaria, recurrir a la reflexin de bajo nivel (java.lang.reflect).stausalospatronesdediseoparalaobtencindelainformacinnecesariaparacrearel BeanInfo. Patronesdediseo:CuandoseimplementaunBeanposeedeterminadaspropiedadesymtodos.Alescribir oleerunadeterminadapropiedadsenecesitanlosmtodosquerealicenesatarea.Paraquelareflexin funcionesedebeacordarparaquelasherramientasRADreconozcanlosmtodoscomotal.Porejemplo,si loquesedeseaesobtenerelvalordeunavariable,elnombredelmtododeber comenzarporgetypara modificarelvalordelmismoseusar set.Estaestandarizacinsonlosdenominadospatronesdediseo. Comosesabe,alimplementarunainterfaz,sedebe,almenos,especificarlascabecerasdelosmtodose implementarlosmtodosdeseados.Javaproporciona SimpleBeanInfo paraayudar,deformaquemediante SimpleBeanInfo tan slo se implementan los mtodos deseados y ni uno ms. Como ventaja al uso de BeanInfocabedestacarqueeldiseadortansloespecificarlosmtodos,eventosypropiedadesquedesee, podromitirelresto. Personalizacin: Es la posibilidad de, en tiempo de diseo, poder modificar las propiedades de un componente(mediantelapaletadepropiedades dedichocomponente).Tambin,paraesefin,sepuede implementar la interfaz Customizer para un determinado Bean. Customizer es una interfaz, la cual proporcionaunaGUIparalamodificacindepropiedadesdeunBeandeterminado.Medianteestainterfazse puedeaadiryborrarlistenersdeunapropiedaddeterminada.Paraellodebecumplirlossiguientespuntos: descenderdejava.awt.Componentodeunadesussubclases. implementarelinterfacejava.beans.Customizer.Estosignificalaimplementacindemtodospara registrar el objeto PropertyChangeListener, y lanzar eventos de cambio de propiedad a dichos listenerscuandoocurreuncambioenelBeanfuente.VaseelAPIdelaclaseCustomizer implementar un constructor por defecto. Asociar el personalizador con la clase fuente mediante BeanInfo.getBeanDescriptor().VaseelAPIdelaclaseBeanInfo Eventos:Informanala JVMdedeterminadasacciones.Cadacomponentetieneohereda determinados eventosaloscualespuederesponder.Deestamanerasepuedenconectarcomponentesentres,deforma queuncomponentesepuedeaadiraunalistadelistenersdeuneventodeotroBeanorigen.Deformaque, cuando se dispara el evento del Bean origen, el/los listeners reacionarn de determinada manera. Por ejemplo,sisepulsaunbotny stetieneuncomponenteescuchaeseevento(yaqueest ensulistade listeneres de ese evento) puede ejercutar determinada accin, por ejemplo modificar el texto de un componenteTextField. Atributos:SondeterminadasvariablesquemodificanelcomportamientooaparienciadeunBean.Esta caractersticasehablardeformamsprofundaenelsiguientetema. Persistencia:MediantelapersistenciasepuedeguardarelestadodeunBean,paraelloseimplementala interfazSerializable.CuandoseguardaelestadodeunBeanseguardaelvalordelaspropiedadesdedicho BeanparaposteriormentecargarelBeanrecuperandoelestadoanterior. Gracias a esto se pueden crear componentes de una manera muy sencilla. Nos han proporcionado la introspeccin, la personalizacin, la persistencia, etc. De una manera intuitiva se podra pensar en una herramientasencillaparacrearaplicaciones.ParaelloestaaplicacinutilizaralafilosofadelosJavaBeans ylasfacilidadesqueofrecen.Porejemplo,sepodrainsertaruncomponenteenlaaplicacin,comopuedeser un botn. Mediante un BeanInfo, introspeccin o mediante ambas herramientas se pueden obtener las
27

propiedades,eventosymtodosque stecomponenteproporcionaymostrarlasalusuarioenunalista.Para esto se usara BeanInfo, que proporciona descriptores de propiedades, eventos y mtodos. De esos descriptoressepodranobtenercontructores,argumentosyengenerallainformacinnecesariaparagenerar cdigo automticamente. Adems, mediante la personalizacin se puede dar al usuario una manera de manipularelvalordelaspropiedadesentiempodeedicin.Oelusuariopodrarelacionarcomponentes medianteeventos.YaqueBeaninfoproporcionadecriptoresdeeventosloquedainformacinparagenerarel cdigo para crear los manejadores de eventos necesarios para dicha comunicacin. Incluso mediante el Beaninfosepuedeasociarunconoquerepresenteelcomponenteenlaherramientadecomposicin. Ytodoestomediantelamanipulacindirecta,esdecir,medianteaccionescomoclickarunelementodeesa listayarrastrarloaunazonadefinidaparalacreacin. AunquelosBeanshansidodiseadosparaquelas herramientasdedesarrollopuedanentenderlos,todaelAPIincluyendoelsoporteparaeventos,propiedades ypersistenciahansidodiseadosparaquelosdesarrolladoresdesoftwarepuedanentenderlosyleerlos rpidamente. UnBeannoheredadeunasuperclaseoimplementaalgunainterface.Seimplementandelamismamanera queunaclasecualquieraperorespetandociertasreglas,delascualeslasprincipalesson: laclaseBeandebeproporcionarunconstructorsinargumentos laclaseBeandebesoportarpersistencia,esdecir,implementarlainterfaceSerializable. DeestamaneracualquierclaseJavapuedeserunBeanconcdigoadicional.LosJavaBeansrespetanuna seriedeconvencionesypatronesdediseo.UnIDEquesoporteBeansdependededichasconvencionesy patronesdediseoparaconocerunBean.ElIDEpodrsaberqumtodos,eventosypropiedadestieneel Bean.TododependedelainformacinqueproporcioneelBeandesmismo.

9.3LainformacindeunBean
BeanInfo es la clase que permite proporcionar informacin acerca del Bean al usuario del mismo. Por ejemplo,conelsiguientecdigoseobtieneunalistademtodosquetieneunBean: publicvoidDescMetodos(BeanInfoj)throwsIntrospectionException{ MethodDescriptor[]descrip=j.getMethodDescriptors(); for(inti=0;i<descrip.length;i++){ metodos.add(descrip[i].getName()); } } paraellosecreaunBeanInfodeeseBeandelasiguientemanera: j=Introspector.getBeanInfo(Clase_Bean); Clase_Bean.descMetodos(j): Comoyasedisponedeesalista,noslosepuedeobtenerelnombredeldescriptordelmtodosinoque tambinsepuedenusarlossiguientesmtodosqueproporcionaapartirdeFeatureDescriptor: attributeNames, getDisplayName, getName, getShortDescription, getValue, isExpert, isHidden, isPreferred, setDisplayName, setExpert, setHidden, setName,setPreferred,setShortDescription,setValue. OatravsdelaclaseObject: clone,equals,finalize,getClass,hashCode,notify,notifyAll,toString, wait Adems, un descriptor de mtodo se construye mediante un objeto de la clase Method
28

(java.lang.reflect.Method)quenosproporcionalossiguientesmtodos: equals, getExceptionTypes(), getModifiers(), getName(), getParameterTy pes(),getReturnType(),hashCode(),invoke(),toString(). Mediantetodaestainformacinsepuedenobtenersucificientesdatosparamostraralusuariocomonombre delmtodo,descripcin,etc.Sepuedeobtenerlaclase,superclases,constructores,etc.queessuficiente informacinparacrearunacabeceradeunmtodoeinclusounjavadocparal.Esms,sepodraninstanciar objetosdeesaclaseenmomentodeedicin.EllomedianteunobjetoListdondesecaptureeleventoderatn y recoja el tem seleccionado de la lista y mediante los mtodos previamente comentados obtener la informacin necesaria para crear la cabecera del mtodo. Esta proceso se puede repetir para eventos y propiedadesdeformasimilar. JavaBeans proporciona informacin de vital importancia para composicin de Beans lo cual encuadra perfectamenteyayudaalafilosofadecomponentesyayudadeformaclaraparaalareutilizacindecdigo.

9.4PropiedadesdeunBean
LaspropiedadesdeunBeansedefinencomolosatributosdiscretosdeuncomponente,talescomocolorde fondo,fuente,etc.Paraqueuncomponenteexpongasuspropiedadessedefinenunaseriedeconvenciones estndares. Las propiedades representan la caracterizacin de un componente, es decir, determinan su apariencia y comportamiento.Comosevi anteriormenteunBeanofreceinteraccionarconlainterfaceCustomizer, sta proporcionabaunaGUIconlacualsepuedemodificar/personalizarlaspropiedadesdeunBean.Ademsde laaparienciasepuededeterminarelcomportamientodedichoBeanyaqueelBeanpuederegistrarelcambio dealgunadesusvariablesyavisaraloslistenersdesulista.Mediantelaintrospeccinypersonalizacinse puedenmodificar/actualizarlasvariablesentiempodeedicin.Laspropiedadespuedenserdelecturao escritura,deformaquelosmtodosdeaccesoomodificacindedichasvariablesdeberantener: Sisetratadeunmtodoparaleerlavariable,debecomenzarelmtodoconget+<nombrevariable>. Enelcasodetratarsedeunmtododeescrituradebercomenzarporset+<nombre_variable>.Esto sedefineparaquelosmtodosdereflexinodeintrospeccinpuedanubicarestoscomomtodos paralaobtencinomodificacindeunavariable. LasherramientasdedesarrollocomoJBuilder,NetBeans,BeanBuilder,etcbuscanestospatrones(setyget) yademselnombredeunavariable.Sedenominaaestopatronesdediseo. LaspropiedadesdeunBeanpuedenser: 1. Propiedadessencillas.EstetipodepropiedaddefineelcomportamientoyaspectodelBean.Por ejemplo el color de background, foreground, layout, etc. Para estas propiedades se definen los mtodossegnlospatronesdediseoparalamodificacinylaconsultadedichasvariables.Luego medianteintrospectorodefinindoloenunBeanInfoomedianteCustomizerelentornodedesarrollo mostraralprogramadoresaspropiedadesylosmtodosentiempodeedicin. 2. Propiedadescompartidas.SonpropiedadesquesecompartenentreBeansydelascualessepuede escucharsucambio,alascualesotroBeanocomponentepuedenapuntarsealalistadelisteners dedichocambio.JavaBeansproporcionaunaseriedefacilidadesquepermitenestasacciones(clases PropertyChangeSupport,PropertyChangeEvent,etc.). 3. Propiedadesindexadas.Estaspropiedadessonsimilaresalaspropiedadessencillasperoconla peculiaridaddequeestetiposonaccedidasdeformasimilaralasmatrices.Aligualquelassencillas, tambindefinenelcomportamientoyaparienciadelBean,aunquesonarraysdeelementos,por tanto,elaccesoastasestardefinidoporunndice.Esdecir,setieneunarraydepropiedades.Los patrones de diseo cambian, eso es, aunque la lectura y escritura se mantiene con get y set respectivamente,sedebeagregaralnombredelavariableloscorchetes[].
29

public<tipo>get<Nombre_propiedad>(intindex); voidset<Nombre_propiedad>(intindex,<Tipo>value); 4. Propiedades restringidas. Este tipo de propiedad parte de la misma idea que las propiedades compartidas;peroadiferenciade stas,enlasrestringidasnosetienequecomunicaratodoslos listenerselcambiodepropiedad.Puedequeporalgunaraznnosedeseequeunodelosoyentes recibaelavisodelcambiodepropiedad,aunqueenrealidadeseloyentequienniegaelcambio. Detodaslaspropidadesanteriormentemencionadas,lasquesonmscomplejasdeimplementarsonlas propiedadescompartidasyrestringidasporloqueseexplicarnacontinuacinconunpocomsdedetalle.

9.4.1Propiedadescompartidas
Comosehavisto,laspropiedadescompartidasbrindanlaposibilidaddecompartireleventodecambioentre unaseriedecomponentesinteresadosqueestanalaescuchadelevento.Estoscomponentesinteresadosse ponenalaescuchadeesapropiedadapuntndoseaunalistaquetieneelcomponenteposeedordela variable(elfuente),deformaquelosoyentesseinscribenoeliminandelalista.Ademselcomponente fuentedebeanunciareleventodecambiodepropiedadatodoslosoyentesdeesapropiedadinscritosenla listadeoyentes. ParaestoJavaproporcionademanerabsicalosiguiente: PropertyChangeSupport

Esta clase permite aadir (addPropertyChangeListener) y borrar (removeProperty ChangeListener)oyentesa/deunalistadeoyentesdeunapropiedadcompartida,tieneunmtodo queavisaalosoyentesdelcambiodevariable(firePropertyChange).Ademsesserializable, esdecir,quepermiteguardaryrestaurarelestadodesuspropiedades,enestecasoguardayrestaura lalistadeoyentes.Estaclase,adems,gestionalalistadeoyentesylaserializa.
PropertyChangeListener

Setratadeunainterfazquerepresentaalosoyentes,ofreceelmtodopropertyChange quese debeimplementaryqueserelquedefinelaaccinarealizarenelmomentodequeeloyentesea avisadodelcambiodepropiedad.ElBeanfuentellamaaestemtodo. Con esto, ya se puede implementar un componente (JavaBean), el cual tendr una propiedad compartida.ParaellosigueunaseriedepasosenloscualessedesarrollaunBeanfuenteyunBean oyentecomoacontinuacinsedescribe.
Beanfuente 1. Importarlasclaseseinterfacesnecesarias,lascualesseencuentranenjava.beans importjava.beans.*; 2. Implementarlosmecanismosnecesariosparaaadiroeliminaroyentesalalista.Estoserealiza instanciandounobjetoXdelaclasePropertyChangeSupport 3. Implementarlosmtodosenloscualesseaadelosoyentes,seeliminanlosoyentesysenotificadel cambioalosoyentes.Elcdigocorrespondienteaestaparteeselsiguiente
30

publicvoidaddPropertyChangeListener(PropertyChangeListenery){ X.addPropertyChangeListener(y); } Seimplementaelmtododeaadirunoyentealalista.Paraelloselepasacomoparmetroel oyentequesedeseaaadiralalistayseusaelobjetoinstanciadoXqueproporcionaelmtodo addPropertyChangeListenerelcualaadeeloyentealalista.Elmtodoinversoeselque eliminaunelementodelalistadeoyentes,removePropertyChangeListener


publicvoidremovePropertyChangeListener(PropertyChangeListenery){ X.removePropertyChangeListener(y); }

4. Establecerunmtodoquecumplalospatronesdediseoquepermitaquelapropiedadcompartida cambiedevalor(set);salvoque,enestecasosedebeimplementarelmtodofirePropertyChangeque avisealosoyentesdesulistadeoyentesdedichocambiodepropiedad.


privateStringetiqueta; publicvoidsetEtiqueta(Stringnueva){ Stringanterior=etiqueta; etiqueta=nueva; X.firePropertyChange(NOMBRE,anterior,nueva); }

Lacadenaetiquetaeslavariablecompartida.Paraavisaralosoyentesdelcambiodevariablese usa el mtodo firePropertyChange, en este caso los parmetros que se le pasan son el nombre descriptivo,elvalorantiguoyelvalornuevodelavariable.Poreso,antesdehacerlallamadaal mtodo se guarda el valor antiguo de la variable. El mtodo firePropertyChange convierte sus parmetrosenunobjetoPropertyChangeEventyllamaalmtodopropertyChange,queesquien debeimplementareloyente,yaquedeesamaneraavisaatodoslosoyentesdelalistadeoyentes.El disparadorseconvierteenuneventodecambiodepropiedad,poresoelnombredescriptivo,yaque seestableceundescriptordeeventosyserelnombrequemuestrealaherramientadedesarrollo. Una vez terminado el fuente se implementa el oyente que escuche el cambio de propiedad del fuente apuntndosealalistadelfuente. Beanoyente 1. Importar lo necesario (java.beans), la clase del oyente debe implementar la interfaz PropertyChangeListener 2. Como el fuente avisa al oyente a travs de un evento, para oirlo el oyente debe implementar propertyChangealcualselepasaporparmetroelevento.Enestemtodoseimplementalaaccin quesedeseaqueeloyenterealicealcambiarlapropiedadcompartida.
publicvoidpropertyChange(PropertyChangeEventevt){ textField1.setText(Cambioenlapropiedad); }

Deestasimplemaneraseimplementaunoyenteyunfuentequecompartenunapropiedadcompartida.Cabe destacar,queunfuentesepuedeimplementarcomooyenteimplementandolosmtodosnecesariosyel oyenteenfuentedeigualmanera.Conloquesepuedetenerinclusounapropiedadcompartidabidireccional. Esdecir,elfuenteyeloyentesecomportandelasdosmaneras. Cdigoejemplo A continuacin se muestra un ejemplo que muestra lo anterior para dejar clara la idea de propiedad
31

compartida.
importjava.awt.*; importjava.awt.event.*; importjava.io.*; importjava.beans.*; publicclassConversionFuenteextendsTextFieldimplementsSerializable,KeyListener{ //LaclaseheredadeTextField(campodetexto)deestaforma,sediceque //elcomponentevaaserunTextField.SeimplementaSerializableparapoder //guardascambiosdepropiedades,engeneralelestadodelcomponente. //KeyListeneresunainterfazparalacapturadeeventosrelacionadoconelteclado. privateStringTextoPesos="";//Estaeslapropiedadcompartida. privatePropertyChangeSupportcambios=newPropertyChangeSupport(this); //SecreaunainstanciadePropertyChangeSupportparaaadir,eliminar //oyentesalalista.Yparaavisarlosdelcambiodepropiedad. publicConversionFuente(){ //Mtodoconstructordelfuente.AquseinicializaelTextFieldy //seagregaunoyenteparaeleventodeteclado super("",25); this.addKeyListener(this); } //Metodoparaaadirunoyentealalistadeoyentes. publicvoidaddPropertyChangeListener(PropertyChangeListenerl){ cambios.addPropertyChangeListener(l); } //Metodoparaeliminarunoyentedelalistadeoyentes. publicvoidremovePropertyChangeListener(PropertyChangeListenerl){ cambios.removePropertyChangeListener(l); } //SeimplementanlosmetodosdeKeyEventalosquesedeseaqueelbean //fuentereaccioneylaaccinarealizar.Sedebenintroducirtodaslas //cabecerasdelosmetodosaunquenoseimplemententodos. publicvoidkeyPressed(KeyEvente){} publicvoidkeyTyped(KeyEvente){} publicvoidkeyReleased(KeyEvente){ StringantiguaCadena=TextoPesetas; TextoPesos=TextoPesos+e.getKeyChar(); cambios.firePropertyChange("TextoPesos",antiguaCadena,TextoPesos); } }

Cuandounateclaespulsadaysoltada(KeyReleased)seavisaalosoyentesdelcambiodepropiedad.Para ello en la cadena que representa los pesos se aade la tecla pulsada, esa cadena nueva surgida de la concatenacinsepasajuntolacadenaantiguaalmtodofirePropertyChangeelcualseencargadeavisarala listadeoyentes. AcontinuacinsemuestraelcdigodelBeanoyentedeleventodecambiodepropiedad.
importjava.awt.*; importjava.io.*; importjava.beans.*; //Estecasoesbastantesimtrico,yaqueeloyenteesotroTextField,portantoel //contructorserigual.Salvoqueaqunohayoyentesdeeventodeteclado. //SeimplementanlasinterfacesPropertyChangeListenerySerializable. publicclassConversorOyenteextendsTextFieldimplementsPropertyChangeListener,Serializable{ publicdoubledolares; publicConversorOyente(){ super("",25); setEditable(false);

32

} //Seimplementaelmanejadordeleventodecambiodepropiedadesdecir, //cuandoelfuenteavisaaloyentedelcambiodepropiedad //eloyentecapturaelavisoenestemtodo,porloquesedefinelaaccin //arealizar.Aquloquesehaceestomarelvalordelapropiedaddelfuente. //firePropertyChangesetransformaenunevento,yenese //firePropertyChangesepasaelvalordelapropiedad,portantodeese //eventoserecuperaelvalordelacadenatraselcambio,mediante //getNewValue,posteriormentesecalculaelnuevovaloryseintroduceen //elTextFieldquerepresentaeloyente. publicvoidpropertyChange(PropertyChangeEventevt){ intpesos=100; StringTextoDolares=(String)evt.getNewValue(); try{ pesos=Integer.parseInt(TextoDolares); }catch(NumberFormatExceptionex){ this.setText("Errordeformato"); } dolares=pesos/11.15; this.setText(String.valueOf(dolares)); } }

9.4.2Propiedadesrestringidas

Enestecasoeloyentepuedeonoquererrecibirelcambiodepropiedad.Paraellotodoesigual,ladiferencia esquehayqueimplementarunmecanismoparaquelosoyentespuedandecirquenoauneventodecambio depropiedad. Cabedestacarquesiunoyenteniegaonoaceptaelcambiotampocoloaceptanlosdemsdelalista.Estas propiedadesseimplementandeigualmaneraconalgunasdiferenciasparaelbeanfuente: 1. Importarjava.beans,secreaunainstanciadeunobjetodeclaseVetoableChangeSupport


privateVetoableChangeSupportX=newVetoableChangeSupport(this);

Unavezdeclaradaslasoperacionesdeaadiryborrarseprocededeigualmanera:
publicvoidaddVetoableChangeListener(VetoableChangeListenery){ X.addVetoableChangeListener(y); }

Comosepuedever,lamaneradeintroduciroyentesesidnticaqueenlaspropiedadescompartidas, salvoqueenestecasoseintroducenoyentesconderechoaveto.Laaccindeeliminarunoyentecon derechoavetoesigual,siguesiendolomismoparaaadirpropidadescompartidas.


publicvoidremoveVetoableChangeListener(VetoableChangeListenery){ X.removeVetoableChangeListener(y); }

2. Elmtodoquecambiaelvalordelapropiedadeslamayordiferencia.Laideaesquehayqueavisar delcambiodepropiedadalosoyentes,perocomoestosnospuedenvetarelevento,enestecaso,se deberestaurarelestadoanterioralcambio.Porloquesedebepropagareleventoantesdelcambio. Sieleventoesvetado,comonosehacambiadonopasanada,sinolovetansehaceelcambioyya. 3. Paraqueelrestodeoyentesrecuperensuestadoantiguo,siunoyentevetaelcambio,sedisparael eventodecambio,peroconelvalorantiguo.

33

Enelcasodeloyentelaideaesigual,esdecir,esigualqueeloyentedepropiedadescompartidas,peroen lugardelainterfazPropertyChangeListenerseimplementalaintefacevetoableChangeListener.Enestecaso el mtodo que captura el evento de cambio de propiedad es el vetoableChange que recibe el evento propertyChangeEvent.Comosemuestraacontinuacin: 1. Importarjava.beans. 2. ImplementarelmanejadorVetoableChange
publicvoidvetoableChange(PropertyChangeEvente){ condicin: silacumple: thrownewPropertyVetoException(VETOELEVENTO); sinolacumple: accinarealizardebidoalcambiodepropiedad }

Aqu hayunacondicindeveto,sisecumplelacondicinquieredecirqueeloyentevaavetarelcambio; porloquelanzaunaexcepcinquecapturaelfuente.Conestoindicaalfuentequelahavetado,paraqueel fuenteacteenconsecuencia,esdecir,elfuentedeberestaurarlapropiedadydecirlealosoyentesqueno hay cambio. Si no se cumple la condicin entonces se procede de igual manera, se realiza la accin correspondientealcambio. Acontinuacinsemuestraelejemploversinoriginaldejava.sun.com
/* *Beanfuente */ importjava.awt.*; importjava.bean.*; //SeimplementaSerializableparaguardarelestadodelcomponente //AdemsseimplementalainterfazvetoableChangeListener publicclassFuenteextendsTextFieldimplementsSerializable,vetoableChangeListener{ privateStringbeanText=; //SedeclaraunobjetodelaclaseVetoableChangeSupportpara //realizarlasaccionesporlasqueaadimosyeliminamosoyentes //yparaelavisoenelcambiodepropiedad. privateVetoableChangeSupportX=newVetoableChangeSupport(this); publicFuente(){ super(,25); } //Seaadenyeliminanoyentesdelalista publicvoidaddVetoableChangeListener(VetoableChangeListenerl){ X.addVetoableChangeListener(l); } publicvoidremoveVetoableChangeListener(VetoableChangeListenerl){ X.removeVetoableChangeListener(l); } //Elcambiosehacehastaquesesabequenosehavetadolaaccin. //Poresoseguardalavariableysolosehaceelcambiodelamisma //sinosehavetado;esdecir,sivuelvedelmtodofireVetoPropertyChange, //porlotantosivuelvesehaceelcambio //(poresolasiguientelineaeselcambiodevariable). //Posteriormenteavisadelcambiodevariable.Todoestoesyaquesiel //oyentevetalaaccinlanzaunaexcepcinyportantoestemtodo //fallara.Sinofallaesporqueeloyenteaceptelcambioynolanzlaexcepcin. publicvoidsetFuente(Stringnueva)throwsPropertyVetoException{ Stringvieja=beanText; X.fireVetoPropertyChange(NOMBRE,vieja,nueva); beanText=nueva;

34

this.setText(nueva); X.firePropertyChange("NOMBRE",vieja,nueva); } //Seramselegantecapturarlaexcepcinconuntrycatch, //deformaqueelcatchserarecuperarelestadodelosoyentes. //try{ //Stringanterior=beanText; //X.fireVetoPropertyChange(NOMBRE,anterior,nueva); //beanText=nueva; //this.setText(nueva); //X.firePropertyChange("NOMBRE",anterior,nueva); //catch(PropertyVetoExceptione){ //beanText=anterior; //Ahoraseavisaalrestodeoyentesdequesehavetadoelcambio //X.firePropertyChange("NOMBRE",nueva,anterior); //Elordendelosargumentosesalrevs,porquedeesamanerase //avisadelarestauracin. //} }

ElcdigodelBeanoyenteeselsiguiente.
/* *Beanoyente */ importjava.awt.*; importjava.beans.*; publicclassOyenteextendsTextFieldimplementsSerializable,vetoableChangeListener{ publicOyente(){ super(,25); setEditable(false); } //Enestemtodosecapturaelevento.Deformaquecuandoelfuente //avisadeuneventovetable,sepuedeversisedebevetarono.Eneste //casosevetasilapropiedadcadenaesDCS,sies //as,lanzaunaexcepcinqueelfuentecapturar(deberacapturar) //SinoesDCS,entoncesnovetayrealizalaaccinenlaqueponeel //textodelTextFieldaNo publicvoidVetoableChange(PropertyChangeEvente)throwsPropertyVetoException{ Stringcadena=(String)e.getNewValue(); if(cadena.equals(DCS)) thrownewPropertyVetoException(DCSVetada); else this.setText(NoesDCS,noseveta); } }

9.5Eventos
LoseventossonsucesosquelaJVMpuedeescuchar.Dichasaccionesocurrensobreelementoscomo puedenserpulsarunatecla,pulsarelratn,etc.Estetemayasehavistoconloscomponentesgrficos,la ideaylosmecanismossonlosmismos. Los componentes son capaces de generar y escuchar eventos de manera similar a las propiedades compartidas.Esdecir,siuneventosucedeelcomponentedisponedemtodosquelostratan.Alsersucesos asncronosynosaberenquemomentoseproducirnnecesitandeuntratamientoespecial.Estosucedede igualmaneraenunacomputadora.Lacomputadoradisponedeunaseriedeperifricosdeentrada/salida (paracomunicarseconlaCPU),losqueenvaninterrupcionesylaCPUalrecibiresasinterrupcionesejecuta unarutinaquetrataesainterrupcin.Esdecirrealizalastareasnecesariasolastareassolicitadasporese recursodelsistema.Vercdigoejemplodelapginadelaasignatura(AppletEvento).
35

EnJavaBeanssedistinguendostiposdeeventos: elquegeneraloseventos(Beanfuente)y losquelosescuchan(Beansoyentes) InicialmenteJavaofrecalaclasejava.awt.Eventparaeltratamientodeloseventos,aunqueyaestobsoletay slosemantieneparalacompatibilidadconimplementacionesanteriores.Anas,es tilporsimplicidad paraexplicarelmecanismodeeventos. Cuandosucedeuneventoserelegaeltratamientodelmismohastaqueencuentreunmtodoquelotrate,casi demanerasimilaralasExceptions.Losmtodos handlerEvent recibenloseventosytratarnlosquese desee: publicbooleanhandlerEvent(Eventevt){ if(evt.target==COMPONENT_A&&evt.ID=ACTION_EVENT){ driver(evt); returntrue; } returnsupe.handlerEvent(evt); } voiddriver(Eventevt){ realizalaaccin; } Unpuedecapturarseono.EnestecasosielCOMPONENTE_Arecibeunaaccinsetratar,esetratamiento serealizar enelmtododriver.SinoserelegaeltratamientoalmtodohandlerEventdelaclasesuperior. Peroestemodeloestobsoleto,yaqueencadaclasehayunhandlerEventalqueserecurresiseavisadeun evento.Enelejemploseidentificalaclasedeeventoydedondeviene.Yunavezidentificadoeleventose llamaalmtodoqueactacuandosucedeesaaccin. EnelejemploseverificaqueIDtieneelevento;sisetieneuncomponenteformadopornumerososbotones, barrasdemen,etc.yhaymuchoseventosquepuedensuceder,elmtodosecomplica,hayquesaberqu evento sucedi para llamar al mtodo necesario. Si adems el evento que sucede es el ltimo que se comprueba,entoncesser lentoyaquehayqueevaluarcondicionalporcondicionalloqueademsnoes eficiente. Seramejoreldiseodeunmodelomsavanzadoyeficienteparaeltratamiento.Dondenosedebeolvidar eltrminodeBeanfuenteylosBeansoyentes,ydondecadatipodeeventotieneasociadounainterfaz. Paraellosehacealgosimilaraloquesehaceconlaspropiedadescompartidas.Esdecir,setendr unBean fuenteylosBeansoyentes,enestecaso,eventofuenteyreceptoresdeeventos.Aleventofuenteseleagrega lalistadeoyentesquevanaescucharlo. Loseventosseencapsulanenunajerarquadeclasesconrazenjava.util.EventObject.Cadatipodeevento tieneasociadaunainterfaz<Evento>Listenerlacualseimplementaparalacapturadeleventoenparticular. Fuentedeevento Estetienelacapacidaddedetectareventosyavisaralosoyentesquetieneapuntadosensuslistasdeoyentes. Aligualqueconlaspropiedadescompartidas, stemantieneunalistaportipodeevento.Alsucederel evento avisa la los elementos de la lista. Al igual que suceda con los mtodos para aadir y eliminar elementosdelalistamantienelaideadepatronesdediseo,enestecasoson: add<Tipo_de_Evento>Listener(); remove<Tipo_de_Evento>Listener();
36

Receptoresdeeventos Sonlosoyentesdeesaslistasquemantenanloselementosfuente.Enlaclasedeloyentedebeimplementar unainterfazdeltipodeeventoconloqueescribir todaslascabecerasdelosmtodoseimplementar el especficoquecapture. addMouseListener(this); //Escuchaelpulsadodelratn.

//Estossonlosmtodosdelainterfaz,deloscualessoloseimplementan //losmtodoscuandosepulsaunbotndelratn.Delrestosolose //especificamoslascabeceras. publicvoidmousePressed(MouseEvente){ this.x=e.getX(); this.y=e.getY(); } publicvoidmouseReleased(MouseEvente){} publicvoidmouseEntered(MouseEvente){} publicvoidmouseExited(MouseEvente){} publicvoidmouseClicked(MouseEvente){} addMouseMotionListener(this); //Escuchaelmovimientodelratn. //Estossonlosmtodosdelainterfaz. publicvoidmouseDragged(MouseEvente){ textField1.setText(tururu); } publicvoidmouseMoved(MouseEvente){} Es un poco engorroso especificar todas las cabeceras. Esto se puede evitar mediante los adaptadores (Adapter).Mediante stosseahorratodoestetrabajo.Esdecir,yanosetienequeespecificartodaslas cabecerasdelosmtodosdelainterfazyaqueeladaptadorimplementatodoslosvacos.As slosetiene quetomareldeseadoysobreescribirlo. Enresumen,cuandouneventoespecficosucede,lafuentedeleventonotificaatodoslosoyentesmediante un mtodo al que le pasa un objeto Event. Este objeto Event es una subclase de la clase java.util.EventObject. As pues, se debe crear una subclase Event propia. Todos los oyentes deben implmentarelmtodorequerido(conelquesenotificadeloseventos).Estoselograagregandoatodoslos oyentes el evento que implementa dicha interface. Un oyente de evento se implementa extendiendo la interfacejava.util.EventListener.Esainterfacenocontienemtodos,sloesunamarcaqueidentificaala interfacecomotal.Lospasosson: 1. CrearlassubclasesdeEventpersonalizadas,debentenerelnombreXXXEvent 2. CrearlainterfaceXXXListenerquecontengalosmtodosqueelobjetooyentedebersobreescribir 3. AgregarunapropiedadalBeanquecontengalalistadeobjetosoyentes. 4. AgregarlosmtodosaddXXXListeneryremoveXXXListener,dondeXXXeselnombredelevento 5. Agregarelmtodoquenotificaratodoslosoyentesregistrados. Sislosedeseanotificaraunslooyentesedebedisparar unaTooManyListenersExceptionalmtodo addXXXListener,ascuandoeloyenteyaatiendealBean,losotrosoyentessonignorados. Acontinuacinsepresentaelejemplodeunfuentedeeventos.

37

importjava.awt.*; importjava.awt.event.*; importjava.applet.*; importjavax.swing.JButton; importjavax.swing.JTextArea; importjavax.swing.*; publicclassAppletEventextendsApplet{ booleanisStandalone=false; BorderLayoutborderLayout1=newBorderLayout(); JButtonraton=newJButton(); JButtonjButton1=newJButton(); JLabeljLabel1=newJLabel(); JTextFieldTECLADO=newJTextField(); TextAreaEVENTOS=newTextArea(); //Seobtienenlosparametros publicStringgetParameter(Stringkey,Stringdef){ returnisStandalone?System.getProperty(key,def): (getParameter(key)!=null?getParameter(key):def); } publicAppletEvent(){} publicvoidinit(){ try{ jbInit(); }catch(Exceptione){ e.printStackTrace(); } } privatevoidjbInit()throwsException{ raton.setBounds(newRectangle(22,167,71,23)); raton.setText("raton"); //Aquisepuedevercomoseagreganlosoyentesparaloseventosderaton. raton.addMouseWheelListener(newAppletEvent_raton_mouseWheelAdapter(this)); raton.addMouseListener(newAppletEvent_raton_mouseAdapter(this)); raton.addMouseMotionListener(newAppletEvent_raton_mouseMotionAdapter(this)); raton.addActionListener(newAppletEvent_raton_actionAdapter(this)); this.setLayout(null); jButton1.setBackground(Color.red); jButton1.setBounds(newRectangle(90,13,135,20)); jButton1.setBorder(BorderFactory.createEtchedBorder()); jButton1.setText("RESET"); jButton1.addMouseListener(newAppletEvent_jButton1_mouseAdapter(this)); TECLADO.setText(""); TECLADO.setBounds(newRectangle(133,167,135,21)); //Aquiagregaalalistadeoyentesdeloseventosdeteclado. TECLADO.addKeyListener(newAppletEvent_teclado_keyAdapter(this)); TECLADO.addActionListener(newAppletEvent_teclado_actionAdapter(this)); jLabel1.setHorizontalAlignment(SwingConstants.CENTER); jLabel1.setText("Teclado"); jLabel1.setBounds(newRectangle(135,196,131,14)); EVENTOS.setText(""); EVENTOS.setBounds(newRectangle(29,42,255,116));

38

this.add(raton); this.add(jButton1); this.add(TECLADO); this.add(jLabel1); this.add(EVENTOS); } //Paraobtenerinformaciondelapplet publicStringgetAppletInfo(){ return"AppletInformation"; } //Paraobtenerinformaciondelosparametros publicString[][]getParameterInfo(){ returnnull; } //Estossonlosmetodosquetratancadaunodeloseventos.Estosseran //invocadosporlasclasesdeloscomponentesoyentes. publicvoidraton_actionPerformed(ActionEvente){ EVENTOS.append("Ratnperfomance\n"); } publicvoidraton_mouseClicked(MouseEvente){ EVENTOS.append("Ratnclicked\n"); } publicvoidraton_mouseDragged(MouseEvente){ EVENTOS.append("Ratnarrastrado\n"); } publicvoidraton_mouseEntered(MouseEvente){ EVENTOS.append("Ratnentered\n"); } publicvoidraton_mouseExited(MouseEvente){ EVENTOS.append("Ratnexited\n"); } publicvoidraton_mouseMoved(MouseEvente){ EVENTOS.append("RatnMoved\n"); } publicvoidraton_mouseWheelMoved(MouseWheelEvente){ EVENTOS.append("Ratnwheelmoved\n"); } publicvoidteclado_actionPerformed(ActionEvente){ EVENTOS.append("Tecladoperfomance\n"); } publicvoidteclado_keyReleased(KeyEvente){ EVENTOS.append("Tecladosoltadodespuesdepulsado\n"); } publicvoidteclado_keyTyped(KeyEvente){ EVENTOS.append("Tecladopulsada\n"); } 39

publicvoidjButton1_mouseClicked(MouseEvente){ EVENTOS.setText(""); } }//class

Acontinuacinsepresentanlasclasesoyentes,todascreanunobjetodeltipoAppletEventeinvocanel mtodoquetrataeleventodelaclaseAppletEvent.
importjava.awt.event.*; classAppletEvent_teclado_keyAdapterextendsKeyAdapter{ privateAppletEventadaptee; AppletEvent_teclado_keyAdapter(AppletEventadaptee){ this.adaptee=adaptee; } publicvoidkeyReleased(KeyEvente){ adaptee.teclado_keyReleased(e); } publicvoidkeyTyped(KeyEvente){ adaptee.teclado_keyTyped(e); } } //****************************************** importjava.awt.event.*; classAppletEvent_teclado_actionAdapterimplementsActionListener{ privateAppletEventadaptee; AppletEvent_teclado_actionAdapter(AppletEventadaptee){ this.adaptee=adaptee; } publicvoidactionPerformed(ActionEvente){ adaptee.teclado_actionPerformed(e); } } //****************************************** importjava.awt.event.*; classAppletEvent_raton_mouseMotionAdapterextendsMouseMotionAdapter{ privateAppletEventadaptee; AppletEvent_raton_mouseMotionAdapter(AppletEventadaptee){ this.adaptee=adaptee; } publicvoidmouseDragged(MouseEvente){ adaptee.raton_mouseDragged(e); } } //****************************************** importjava.awt.event.*; classAppletEvent_raton_mouseAdapterextendsMouseAdapter{ privateAppletEventadaptee; 40

AppletEvent_raton_mouseAdapter(AppletEventadaptee){ this.adaptee=adaptee; } publicvoidmouseClicked(MouseEvente){ adaptee.raton_mouseClicked(e); } publicvoidmouseEntered(MouseEvente){ adaptee.raton_mouseEntered(e); } publicvoidmouseExited(MouseEvente){ adaptee.raton_mouseExited(e); } } //****************************************** importjava.awt.event.*; classAppletEvent_raton_actionAdapterimplementsActionListener{ privateAppletEventadaptee; AppletEvent_raton_actionAdapter(AppletEventadaptee){ this.adaptee=adaptee; } publicvoidactionPerformed(ActionEvente){ adaptee.raton_actionPerformed(e); } } //****************************************** importjava.awt.event.*; classAppletEvent_raton_mouseWheelAdapterimplementsMouseWheelListener{ privateAppletEventadaptee; AppletEvent_raton_mouseWheelAdapter(AppletEventadaptee){ this.adaptee=adaptee; } publicvoidmouseWheelMoved(MouseWheelEvente){ adaptee.raton_mouseWheelMoved(e); } }

Enlapginadelaasignaturapuedenencontrarsediversosbeansqueimplementanlosaspectosquesehan mencionadoanteriormente.

10.ArchivosJAR
LacompresindearchivosenJavaserealizaconelformatoJAR(JavaARchives),estossonarchivosque comprimen a otros archivos tales como archivos ejecutables (class), archivos de sonido, archivos de imgenes,etc.LosarchivosJARtienenlaparticularidaddequealprovenirdeJavasonmultiplataforma. Estosarchivospuedenemplearseparacomprimirunproyectodesoftwareenun nicoarchivoquepuede ejecutarsesinnecesidaddedescomprimirlo.Asimismo,losarchivosJARsonparticularmente tilespara JavaBeansyaplicacionesdered(applets)yaqueconunasolainvocacion/conexinsepuedecargaruna
41

aplicacincompleta; silaaplicacinnoest comprimidasetendraquehacerunaconexinporcada archivoquefuesenecesario. LosarchivosJARestnbasadosenelformatodecompresinZIP,as quealavezqueincluyeenunsolo archivoavarios,tambinlesreducedetamao.AdicionalmenteelarchivoJARpuedecontenerarchivos firmadelautor,demaneraquepuedacomprobarsesuorigen.UnarchivoJARes: unformatomultiplataforma elnicoformatoquepuedeincluiraudio,imagenesyarchivosejecutables(class) totalmentecompatibleconapplets unestndarabiertototalmenteextensibleyescritoenJava.awt.Canvas elmtodopreferidoparaponervariaspiezasenunappletJava

10.1CmocrearunJAR
UnarchivoJARpuedecrearseconlaherramientajarincludaenelJDK.Lasinopsiseslasiguiente: jar[opciones]destino[archManifiesto]archivosParaComprimir Dondelasopcionespuedenser: c t x xarchivo f m v o M creaunnuevoarchivo listalatabladecontenido extraetodoslosarchivos archivoextraeelarchivoindicado seusaparaindicarelnombredelarchivo.Siseomiteelcomandojarasumequeseteclearel nombredesdelaconsola;sielarchivoseestcreandoenviarlasalidaalaconsola indicaqueelprimerargumentoserelnombredelarchivomanifiesto describeenconsolaloqueesthaciendo soloagrupalosarchivossincomprimirlos. tilcuandoeljarresultanteseinvocardesdeelclasspath nocreaautomticamenteelarchivomanifiesto

Ejemplos Crearunarchivo: jarcvfMiArchivo.jar*.class jarcvfMiArchivo.jarDirClasses/*.class jarcvfMiArchivo.jararchX.txtDirClasses/*.class jarcfsoundmap.jar*.classimage.gifsound.au Verelcontenidodeunarchivo: jartvfarchivo.jar ExtraerlosarchivosdelJAR: jarxfarchivo.jarMETAINF/MANIFEST.MF ExtraerunsoloarchivodelJAR: jarxfarchivo.jararchDeseado.ext

10.2InvocacindearchivosJAR
Applet ParaincluirarchivosJARenunappletsedebeespecificarquarchivoinicialdeseacargarsedelarchivoJAR, estosehaceconelparmetroARCHIVE,eldirectoriodondeest elJARdebeserrelativoalapplet.Por
42

ejemplo:
<appletcode=Animator.class archive="jars/animator.jar" width=460height=160> <paramname=foovalue="bar"> </applet>

As secargantodoslosarchivosdelarchivoJARiniciandopor Animator.class,cualquierarchivoquedebe cargarsecomopartedelappletsebuscar primeroenel animator.jar,encasodenoencontrarseah se intentardescargarlodesdeelsitiodondeseencuentreelapplet. PuedencargarsevariosarchivosJAR,loscualesdebensepararsepor,,porejemplo:


<appletcode=Animator.class archive="classes.jar,images.jar,sounds.jar" width=460height=160> <paramname=foovalue="bar"> </applet>

Ntese que debe haber un espacio entre los diferentes archivos JAR. Tambin es necesario respetar la convencindelnombredelosarchivosJAR,debenescribirsetalcualsea,conmaysculasyminsculas. Aplicaciones Paraejecutararchivoscontenidosenunjarcomounaaplicacinesmssencilloqueparaelcasodeapplets. nicamenteseagregalaopcinjaralintrpretejava,porejemplo:
$javajararchivo.jar

10.3Archivomanifiesto
En los archivos JAR puede agregarse un archivo manifiesto, el cual generalmente se llama META INF/MANIFEST.MFycontienemetainformacinacercadelosarchivosdelJAR.Pordefectoelcomando jarcreaunarchivomanifiestoquecontienemensajesMD5(MessageDigestalgorithm5)ySHA(Secure HashAlgorithm)paracadaarchivo.MD5ySHAsonfuncionescriptogrficasparahash. Lainformacindelarchivomanifiestolaemplealaaplicacindesempaquetadora(laqueuseelarchivo JAR)paraverificarquelosarchivoscomprimdosnosoncorruptos.

43