Vous êtes sur la page 1sur 90

Programacinen GUIs

Tema3:Programacinen entornosgrficosdeusuario
1.Introduccin 2.Evolucinhistrica 3.Caractersticasdela programacinenGUIs 4.Gestindeeventos 5.Arquitecturadeunaaplicacin conGUI 7.ProgramacindeGUIsenJava 8.ComponentesSwing 9.PrimerospasosenSwing 10.Gestoresdededistribucin 11.DiseandonuestroJFrame 12.Capturadeeventos 12.Cuadrosdedilogo 13.Teclasrpidas 14.LoslooksdeSwing

Programacinen GUIs

Introduccin
EntendemosporInterfazGrficadeUsuario(GUI)al softwarequepermitelainteraccinentreelusuarioy losserviciosqueproporcionaelsistemaoperativo, utilizandoparaellounarepresentacingrficaintuitiva dealtonivel Lainformticamodernanopuedeentendersesinel impactoquesupusolageneralizacindelosentornos grficosdeusuarioapartirdelos80 Hoyenda,lamayorpartedelasaplicaciones destinadasausuariosfinalesserealizanparaestetipo deentornos
Introduccin

Programacinen GUIs

LamayoradelosGUIsdepropsitogeneralsiguen lallamadametforadeescritorio,yutilizanunsistema deventanas.Paralainteraccinconelusuario disponendeunnmeromsomenosgrandede elementosowidgets:botones,editores,etc. Novamosaestudiaraqulascaractersticasdelas interfacesdeusuario,sudiseooimplementacin (asignaturaInterfazPersonaOrdenador) Noscentraremosenlascaractersticasdela programacinenestetipodeentornosyenuna descripcingeneraldelcambioquesuponerespectoa laprogramacinclsicaylasnuevasposibilidadesque aporta
Introduccin

Programacinen GUIs

Evolucinhistrica
LaaparicindelosGUIsfueposibleporlamejorade lasprestacionesdelosordenadores.Laescasa potenciadelosordenadoreshastaprincipiosdelos70 hacaimpensabledesperdiciarCPUenlainterfazcon elusuario Hastaentonceselusuariodisponadeunamnima interfazenmodotexto,bsicamenteunalneadonde setecleabanloscomandosdelS.O.,enunnivelmuy cercanoalamquina

Evolucinhistrica

Programacinen GUIs

Losorgenes
Alto(1973).DesarrolladoenelXeroxPARC,Altofue elprimerordenadorqueincorporabaratnyun sistemaoperativoconunainterfazgrficadeusuario. Sinembargosuprecioeraprohibitivo,loqueimpidi sudifusinfueradelmbitodeuniversidadesy centrosdeinvestigacin

Star(1981).XeroxdesarrollStarconla intencindepresentarunordenadorpersonal paraelmbitodelaofimtica.Implementapor primeravezlametforadeescritorioygeneraliza elusodeiconosyventanassolapadas.Su influenciaenAppleyelrestodeGUIsque siguieronfueenorme


Evolucinhistrica

Programacinen GUIs

LosentornosoperativosdeAppleyNext
System1(1984).SteveJobstomolas ideasdesarrolladasenelXeroxPARCpara disearelsistemaoperativodelnuevo ordenadorqueibaalanzaralmercadosu compaaApple,elMacintosh.Este ordenadoracerclainformticaalusuario domsticocomonuncaanteshabaocurrido GS/OS(1988).ElSystem1 evolucionrpidamentehastael GS/OS,queincorporabaexplotabael soportedecolor(200x320x16colores) ysonidodelAppleIIGS,ascomosu mayorpotencia.Losordenadores Applesehicieronpopularesporlo sencilloeintuitivoqueerasuuso
Evolucinhistrica

Programacinen GUIs

System7(1991).Representunenorme saltofrentealossistemasanteriores,al incluirsoportedereddeforma transparente,direccionamientodememoria de32bitsymemoriavirtual,ascomo tecnologascomoDraganddrop,Quicktime (multimedia)yTruetype(fuentesmejorados)

NextStep(1988).SteveJobsfue despedidodeAppleyfundunanueva compaa:Next.LosordenadoresNextysu sistemaoperativoNextStepestabanllenos deinnovacionesybuendiseo.Como curiosidad,ellenguajedeprogramacin nativodeNextSteperalelObjetiveC,un lenguajeOOP

Evolucinhistrica

Programacinen GUIs

XWindow
ElsistemaXWindowfuedesarrolladoenelMITen1984,apareciendola primeraversincomercialen1986.XWindownoeraunGUIens,sino simplementeunsistemadeventanasconcapacidaddefuncionaratravsde lared.ParatrabajarconXWindoweranecesarioungestordeventanas,que eraelqueproporcionabaellookandfeeldefinitivo

TWM.Fueunodelosprimeros gestoresdeventanasparaX. Realmenteproporcionabalomnimo paratrabajarconlamquina

Evolucinhistrica

Programacinen GUIs

Motif.Elprimergestordeventanas paraXWindowqueproporcionabauna buenacalidaddepresentacin. Duranteaoseltoolkitde programacinMotifhasidoel predilectoparalosprogramadoresen XWindow

OpenWindows.Hasidoelgestorde ventanasutilizadoporSUNdurante aos.Decaractersticassimilaresa Motif,conunlookmuypeculiar.Las primerasversionesdeLinuxtambin utilizabanestegestordeventanas, antesdelaaparicindeGnomeyKDE


Evolucinhistrica

Programacinen GUIs

KDE.FuedesarrolladoparaLinux, conlaintencindecompetircon Windowsenaspecto,facilidaddeuso ycantidaddeaplicaciones.Eltoolkit deprogramacinesQtdelacompaa TrolltechparaC++

Gnome.Esfrutodeunproyectoque surgiconelobjetivodeconstruirun gestordeventanasigualomejorque KDEperoutilizandountoolkitabierto desarrolladoporlacomunidad(GTK). Sinembargoelresultadonollegaal niveldeKDE.AdemsGTKest basadoenC,ynoesnidelejostan fcildeusarypotentecomoQt


Evolucinhistrica

Programacinen GUIs

WindowsyOS/2
Windows1.0(1985).Fueunintento deMicrosoftparaimplantarlafilosofa delosGUIsdeAppleenlaplataforma PC.Elresultadoerarealmente bastantepobre.Surepercusinfue francamenteescasa

Windows3.1(1992).ElprimerGUIde Microsoftconverdaderoxito, ResponsabledelgransaltodelPCal modogrfico.Eratodavainferioren prestacionesalosGUIsdeApple, aunqueladistanciaseacortaba.

Evolucinhistrica

Programacinen GUIs

OS/2(1992).Elentornooperativode IBM,conlaintencindecompetircon WindowsenelmercadodelosPCs. ErasuperioraWindows3.1ytuvo ciertapopularidad.OS/2noeraun simpleentornogrficodeventanas,sin unsistemaoperativocompletode32 bits,nobasadoenMSDOS

Windows95(1995).Visualy funcionalmenterepresentungran saltodesdeWindows3.1aunque internamenteseguasiendoun sistemaoperativode16bits

Evolucinhistrica

Programacinen GUIs

CaractersticasdelaprogramacinenGUIs
LaprogramacinenunGUIdeterminadorequiereel usodeuntoolkit(oSDK)paraeseGUI,enellenguaje deprogramacinquequeramosutilizar
ExistesiempreuntoolkitoficialqueproporcionaelfabricantedelGUI, normalmenteparaCoC++.PorejemploMFCparaprogramacinenWindows Tambinexistentoolkitsalternativosdesarrolladosporterceros,yasean comercialesogratuitos.Porejemplo,OWL(C++)deBorlandparaWindows Finalmentetambinesposibleelusodeuntoolkitmultiplataforma,comoGTK+ (paraC),QtoFltk(ambosparaC++)

LaestructuradeunGUIesdeformanaturalorientada aobjetos.Eldesarrolloconuntoolkitorientadoa objetosesmuchomssencilloyrpido


Caractersticasdela programacinenGUIs

Programacinen GUIs

LaprogramacindeaplicacionesparaunGUIimplica uncambioradicaldefilosofayestructuraenlos programas Unprogramatradicionaltieneunaestructuralineal, conelcdigorepartidoenunaseriedefuncionesu operaciones.Existeunafuncinuoperacinprincipal dondecomienzalaejecucinyapartirdeahse encadenanlasllamadasdeunasfuncionesaotras hastaqueenunpuntodeterminadoacabalaejecucin


Inicio Tarea Programa 1 Tarea 2 ... Tarea n Fin

Caractersticasdela programacinenGUIs

Programacinen GUIs

EncambiolaprogramacinenGUIsesorientadaa eventos.Lamayoradeloseventossonsucesos asncronosproducidosporlainteraccindelusuario conlaaplicacin,yestnligadosaalgnelementode lainterfaz.Algunosejemplosson:


Pulsarunbotn Cambiareltamaodeunaventana Moverunabarradedesplazamiento Pulsarunatecla Tocaralgunodelosbotonesminimizarmaximizarcerrardelaventana Hacerunclickderatnsobreunelementodeterminado

Algunoseventosnorelacionadosdirectamenteconel usuarioson:
Aparicindeunaventana Tickdeunrelojprogramadoconantelacin
Caractersticasdela programacinenGUIs

Programacinen GUIs

LamayorpartedelcdigoenunprogramaparaunGUI estenlosllamadosmanejadoresdeeventos.Cada manejadorseencargaderealizarelconjuntode accionesasociadasauneventodeterminado.Existeun gestordeeventos(quepuedeproporcionareltoolkit) queseencargaderecibirtodosloseventosdela aplicacinyllamaralmanejadoradecuado


Manejador 1

Manejador 2 Inicio Inicializacin Gestor de eventos Manejador 3 Fin

Manejador 4

Caractersticasdela programacinenGUIs

Programacinen GUIs

LaprogramacinenGUIssueleserunprocesoiterativo detrespasos Elprimeroconsisteendisearlainterfazdeunaparte delaaplicacin,utilizandoloswidgetsdisponiblesenel toolkitdedesarrolloeincluyedostareas:


Posicionarloswidgetsyestablecersusdimensiones Modificarsuscaractersticasvisualesyfuncionales(ttulos,colores, comportamiento)

Enelsegundoserealizalacapturadeloseventosdela interfazquepermitanimplementarlafuncionalidad requerida Eneltercerpaso,seimplementacadaunodelos manejadorescorrespondientesaloseventoscapturados


Caractersticasdela programacinenGUIs

Programacinen GUIs

Losentornosmodernosorientadosacomponentes comoDelphi,C++Builder,VisualBasicetc.permiten realizarlasdosprimerospasosdemaneravisualenlo queseconocecomofasedediseo

Caractersticasdela programacinenGUIs

Programacinen GUIs

Unavezrealizadoeldiseo,losentornosdedesarrollo eligenunadelassiguientesestrategias:
Salvareldiseoylaspropiedadesenficherosocultosespecialesqueson compiladosjuntoalcdigo(Delphi,C++Builder,VisualBasic) Generarelcdigocorrespondientedelainterfazqueeldesarrolladorcompletacon supropiocdigo(NetBeans)

Caractersticasdela programacinenGUIs

Programacinen GUIs

Gestindeeventos
Comoacabamosdever,enunprogramaparaunGUI latareafundamentalarealizaresgestionaradecuada menteloseventosrecibidos Lainformacinasociadaauneventosuelesercomo mnimouncampoindicadordeltipodeeventoyel identificadordelelementoquegeneradichoevento (botn,ventana,etc.) Unaspectofundamentaleneldiseodeuntoolkites laformaenqueseproducelaconexinentreelgestor deeventosylosmanejadores
Gestindeeventos

Programacinen GUIs

Enlostoolkitsmsbsicosyprimitivos,quesuelen serparaellenguajeC,elprogramadorrealizala implementacindelgestordeeventosylallamada directaalosdistintosmanejadores Durantelainicializacindelaaplicacindebepasarse altoolkitelnombredenuestrogestordeeventos


int main() { ... /* Indicar al toolkit la funcin para la gestin de eventos */ gestorEventosGUI(gestorEventos); ... } void gestorEventos(Evento e) { switch(e.tipo) { case VENTANA_ABRIR: ventanaAbrir(e); break; case VENTANA_CERRAR: ventanaCerrar(e); break; case BOTON_PULSADO: botonPulsado(e); break; ... } }
Gestindeeventos

Programacinen GUIs

Entoolkitsmssofisticadosesposibleindicarpor cadaeventoquenosintereseunafuncinquehace lasvecesdemanejador(CALLBACK).Elgestorde eventosestintegradoeneltoolkit ElusodeCALLBACKssuelefavorecerelusode elementosnomuyaconsejables:variablesyobjetos globales,punterosavoid,etc.


int main() { ... /* Indicar al toolkit los distintos manejadores */ manejadorEventoGUI(VENTANA_ABRIR, ventanaAbrir); manejadorEventoGUI(VENTANA_CERRAR, ventanaCerrar); manejadorEventoGUI(BOTON_PULSADO, botonPulsado); ... }

Gestindeeventos

Programacinen GUIs

Java utiliza un sistema basadoenelpatrndediseo Observador Elelementoquegenerauneventoadmiteunalistade observadoresdelmismo Elelementoenviarunanotificacinalosobservadores cadavezquesegenereelevento


// Definicin de una clase observador del procesamiento de pulsaciones de botn class procesamientoBoton implements ActionListener { void actionPerformed(ActionEvent e) { // Procesar evento de pulsacin de botn } } // Suscribir el observador procesamientoBoton al evento de pulsacin de este botn boton1.addActionListener(new procesamientoBoton());

Gestindeeventos

Programacinen GUIs

OtrostoolkitscomQtdisponendemecanismos especficos.IncorporaunaextensinaC++quepermite enlazaruneventoproducidoporunelementoconuna operacindeunobjetodeterminado(SIGNAL/SLOT) MFCtambinhaceusoextensivodemacrosespeciales paraconectarloseventosconciertasoperacionesdela clasequerealizansuprocesamiento

Gestindeeventos

Programacinen GUIs

ArquitecturadeunaaplicacinconGUI
LaarquitecturadeunaaplicacinconGUItieneuna seriedenivelesqueenglobanclasesquerealizan distintastareas
Capadepresentacinointerfaz Capadeaplicacinodeldominiodelproblema Capadepersistencia

Capa de presentacin

Capa de aplicacin

Capa de persistencia

Arquitecturadeuna aplicacinGUI

Programacinen GUIs

Lacapadepresentacinointerfazcontienelosobjetos quepermitenmostrarlainformacinalusuarioy gestionarlainteraccinconelmismo.Atencin:es dependientedeltoolkitutilizado Lacapadeaplicacinodedominiodelproblema contienelasobjetosquemodelanlasolucindel problema(objetosdenegocio).Eslacapams importanteypuedeserreutilizadatotaloparcialmente enmltiplesaplicacionessimilares Lacapadepersistenciacontieneelcdigonecesario paraalmacenarlosobjetosdenegocioenbasesde datosoficheros.Puedeserdependientedelabasede datos/formatodeficheroutilizado
Arquitecturadeuna aplicacinGUI

Programacinen GUIs

Esfundamentalrespetarsiempreestadivisinde tareasentrelasclasesdeunaaplicacin Mezclarenunamismaclaseaspectosfuncionalidades deestostresnivelesesungravefallodediseocon diversasconsecuencias


Propensinaerrores Dificultadparaentendersufuncionamiento Mantenimientoylocalizacindeerrorescompleja Imposibilidaddereutilizacin

Otrareglaimportanteaseguiresprocurarquelas clasesdecadanivelsecomuniquennicamenteconlas delnivelinmediatamenteinferior EnlaasignaturaInterfazPersonaOrdenadorse estudiarconmayordetalleestetema


Arquitecturadeuna aplicacinGUI

Programacinen GUIs

ProgramacindeGUIsenJava
PuestoqueJavapretendeserunlenguajemultipla taforma,eldiseodeltoolkitparaprogramacindeGUIs sehizopensandoenquelasaplicacionestuvieranun buenaspectoencualquierplataformaperoindepen dientedecualquierGUIespecfico EstetoolkitsedenominAWT1.0(AbstractWindow Toolkit)

Programacin deGUIsenJava

Programacinen GUIs

RealmentelasaplicacionesAWT1.0tenanunaspecto mediocreyunescasonmerodeelementos.Ademssu diseointernoeramuydeficiente LasituacinmejoralgoconAWT1.1,peronofue hastaJava1.2cuandoapareciSwing,untoolkit completamentenuevo,conundiseointernoorientadoa componentesyunlookmuchomssatisfactorio

Programacin deGUIsenJava

Programacinen GUIs

ApesardequeSwingtieneunestilovisualpropiopor defecto,puedetambinutilizarunaspectoMotif, WindowsoApple.Estosltimossloenlas plataformascorrespondientes.Ademspuedecambiar deaspectoentiempodeejecucin

AspectoSwingpordefecto

AspectoWindows

AspectoMotif

Programacin deGUIsenJava

Programacinen GUIs

ComponentesdeSwing
Componentescontenedores(sirvenparacontenery organizarotroscompontes):
JFrame.Representaunaventanabsica,capazde contenerotroscomponentes.Casitodaslas aplicacionesconstruyenalmenosunJFrame JDialog,JOptionPane,etc.Loscuadrosdedilogo sonJFramerestringidos,dependientesdeun JFrameprincipal.LosJOptionPanesoncuadrosde dilogosencillospredefinidosparapedir confirmacin,realizaradvertenciasonotificarerrores. LosJDialogsoncuadrosdedilogogenerales, normalmenteutilizadosparapeticionesdedatos
Componentesde Swing

Programacinen GUIs

JInternalFrame.Consistesimplementeenuna ventanahija,quenopuedesalirdeloslmites marcadosporlaventanaprincipal.Esmuycomnen aplicacionesquepermitentenervariosdocumentos abiertossimultneamente

JPanel.Unpanelsirveparaagruparyorganizar otroscomponentes.Puedeestardecoradomediante unbordeyunaetiqueta

JScrollPane.Esunpanelquepermitevisualizarun componentedeuntamaomayorqueeldisponible medianteelusodebarrasdedesplazamiento

Componentesde Swing

Programacinen GUIs

JSplitPane.Permitevisualizardoscomponentes, unoacadalado,conlaposibilidaddemodificarla cantidaddeespaciootorgadoacadauno

JTabbedPane.Permitedefinirvariashojascon pestaas,quepuedencontenerotroscomponentes. Elusuariopuedeseleccionarlahojaquedeseaver mediantelaspestaas

JToolBar.Esuncontenedorquepermiteagrupar otroscomponentes,normalmentebotonesconiconos enunafilaocolumna.Lasbarrasdeherramientas tienenlaparticularidaddequeelusuariopuede situarlasendistintasconfiguracionessobreelframe principal

Componentesde Swing

Programacinen GUIs

Controlesbsicos:
JButton,JCheckBox,JRadioButton.Distintostiposde botones.Uncheckboxsirveparamarcarunaopcin.Un radiobuttonpermiteseleccionarunaopcinentrevarias disponibles JComboBox.Lascomboboxesolistasdesplegablesque permitenseleccionarunopcinentrevariasposibles

JList.Listasquepermitenseleccionarunooms elementos JTextField,JFormattedTextField,JPasswordField. Distintostiposdeeditores.JFormattedTextFieldpermite indicarelconjuntodecaractereslegalesquepueden introducirse.JPasswordFieldnomuestraelcontenido JSlider.Unsliderpermitenintroducirunvalor numricoentreunmximoyunmnimodemanera rpida Componentesde
Swing

Programacinen GUIs

JSpinner.Permitenseleccionarunvalorentreunrangode opcionesposibles,aligualquelaslistasdesplegables, aunquenomuestrantallista.Losvalorescambianalpulsar losbotonesdedesplazamiento.Tambinsepuedeintroducir unvalordirectamente

Mensdesplegables.Existendostiposdemens: JMenuBar,queconsisteenunabarrademens desplegablesenlapartesuperiordelaaplicacin,y JPopupMenu,unmenqueseobtienealpulsarconelbotn derechodelratnsobreunazonadeterminada.Losmens estncompuestospordistintositems:JSeparator(unalnea deseparacinentreopciones),JMenuItem(unaopcin ordinaria),JMenu(unsubmenu),JCheckboxMenuItem(un opcinenformadecheckbox)ofinalmente JRadioButtonMenuItem(unaopcinenformaderadio button
Componentesde Swing

Programacinen GUIs

Controlesespecializados:
JColorChooser.Consisteenunselectordecolores

JFileChooser.Permiteabriruncuadrodedilogoparapedir unnombredefichero JTable.Permitevisualizarunatabladeinformacin,con capacidadparapermitirlaedicinporpartedelusuario.La tablapuedeincluirtexto,imgenesyalgunoscontroles bsicoscomocheckbuttonsycomboboxes JTree.Sufuncinesmostrarinformacindetipojerrquico


Componentesde Swing

Programacinen GUIs

Controlesnointeractivos(muestranalgntipode informacinperonointeraccionanconelusuario):
JLabel.Permitesituaruntexto,untextoconunaimageno unaimagennicamenteenlaventana.Nosoniteractivosy puedeutilizarsecdigoHTMLparaescribirtextoenvarias lneasyconvariosatributos JProgressBar.Permitemostrarqueporcentajedeltotalde unatareaarealizarhasidocompletado JToolTip.Consisteenunaetiquetadeayudaquesurgeal cabodeunosegundossobrelaposicinapuntadaporel cursor.Normalmentenoesnecesarioutilizardirectamentela claseJToolTip,sepuedeestablecerparacualquier componentedelaventanamediante:e.setToolTipText(sta eslaetiqueta)
Componentesde Swing

Programacinen GUIs

PrimerospasosenSwing
Casisiempre,elprimerpasoalahoradeconstruiruna aplicacinescrearunJFrameinicial PordefectounJFramesecreadeformainvisible,as quequeesnecesarioactivarsuvisualizacinmediante laoperacinsetVisible()
import javax.swing.JFrame; public class AppHolaMundo { public static void main(String[] args) { JFrame f = new JFrame("Prueba"); f.setVisible(true); } }

Primerospasos enSwing

Programacinen GUIs

Sinembargo,alcerraresteframelaaplicacinno termina,sequedacolgada.Estoocurreporquees necesarioasociarlaaccindecerrarelJFrameconla finalizacindelaaplicacin Podemosrealizarestaasociacinmediantela operacinsetDefaultCloseOperation()


import javax.swing.*; public class AppHolaMundo { public static void main(String[] args) { JFrame f = new JFrame("Prueba"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }

Primerospasos enSwing

Programacinen GUIs

Loscomponentesseaadenalpaneldecontenidosdel JFrame,accesiblemediantegetContentPane().add() ElJFramedisponedeunaoperacinadd()queyahace estodirectamente


VamosacrearunJLabelconeltextoHolamundoylovamosaaadiral JFrame.ConestoyatenemosunHolamundoenSwing
import javax.swing.JFrame; public class AppHolaMundo { public static void main(String[] args) { JFrame f = new Jframe("Prueba"); // Equivalente a f.getContentPane().add(new JLabel...) f.add(new Jlabel (Hola mundo)); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }

Primerospasos enSwing

Programacinen GUIs

Gestoresdedistribucin
Unadelastareasmstediosasalahoradedisearun frameconvarioselementosenelinterioresposicionary establecereltamaodecadaunodeestoselementos. Dosalternativas:
Posicionarcadaunoloselementosindicandoposicionesytamaos.Estediososi noserealizadeformainteractiva.Ademsalcambiareltamaodelframelos elementospuedendesajustarse Utilizarungestordedistribucinqueseencargadedistribuirloscomponentesde formaautomtica.Puedesercomplicadoobtenerladistribucinquerealmente deseamos

Gestoresde distribucin

Programacinen GUIs

EnlaprogramacinconSwingserecomiendaelusode ungestordedistribucin(LayoutManager)parala distribucindeloscomponentesenframesycuadrosde dilogo Podemosestablecerelgestordedistribucinparalos elementossituadosenunpanelmediante panel.setLayout(<gestordedistribucin>) Podemosanularladistribucinautomticamediante panel.setLayout(null)eindicarcoordenadasabsolutas Paraestablecereltamaodelframequecontienelos componentestenemosigualmentedosopciones:
Utilizarframe.pack()paraqueajustesutamaoaldeloscomponentesdesu interior.Estaeslaopcinmsrecomendable Establecersutamaoindicandoanchoyaltomedianteframe.setSize()
Gestoresde distribucin

Programacinen GUIs

Vamosadisearunainterfazparaelejemplodelacuentasbancariasdeltema2. Empezaremosaadiendoetiquetas(JLabel)yeditores(JTextField)parapoder visualizarlainformacindelacuenta


public class AppBanco { public static void main(String[] args) { JFrame f = new JFrame("Gestin de Cuentas"); f.add(new f.add(new f.add(new f.add(new f.add(new f.add(new f.add(new f.add(new JLabel ("Cdigo")); JTextField (8)); JLabel ("Titular")); JTextField (30)); JLabel ("Saldo")); JTextField (8)); JLabel ("Inters")); JTextField (4));

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }

Elresultadonoescorrectopordosrazones.EnprimerlugarSwingutilizapor defectoelgestordedistribucinBorderLayoutquenoesvlidoparanuestro ejemplo.Ademslaventananotieneeltamaoadecuadoparavisualizarlos componentes Gestoresde


distribucin

Programacinen GUIs

ElgestordedistribucinBorderLayoutpermiteun componentepegadoaunodelosbordesdelpaneloen elcentrodelmismo.Pordefectoloscomponentesse situanjuntoalbordeizquierdo


public class AppBanco { public static void main(String[] args) { JFrame f = new JFrame("Gestin de Cuentas"); f.add(new f.add(new f.add(new f.pack(); JLabel("Este"), BorderLayout.WEST); JLabel("Centro"), BorderLayout.CENTER); JLabel("Oeste"), BorderLayout.EAST); // Ajustar Frame a los contenidos

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }

Gestoresde distribucin

Programacinen GUIs

ElgestordedistribucinBoxLayoutorganizalos componenteshorizontaloverticalmente,ajustandolos componentesalespaciodisponible

public class AppBanco { public static void main(String[] args) { JFrame f = new JFrame("Gestin de Cuentas"); f.setLayout( new BoxLayout(f.getContentPane(), BoxLayout.X_AXIS)); f.add(new JLabel("Cdigo")); f.add(new JTextField(8)); f.add(new JLabel("Titular")); f.add(new JTextField(30)); f.add(new JLabel("Saldo")); f.add(new JTextField(8)); f.add(new JLabel("Inters")); f.add(new JTextField(4)); f.pack(); // Ajustar JFrame a los contenidos f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } } Gestoresde distribucin

Programacinen GUIs

UtilizandoelparmetroX_AXISoY_AXISconseguimos unadistribucinhorizontalovrtical

ElgestordedistribucinFlowLayoutessimilaral BoxLayouthorizontalperoloscomponentesmantienen susdimensiones

Gestoresde distribucin

Programacinen GUIs

ElgestordedistribucinGridLayoutorganizalos componentesenunarejilladeceldasdelmismotamao
public class AppBanco { public static void main(String[] args) { JFrame f = new JFrame("Gestin de Cuentas"); f.setLayout(new GridLayout(4,2)); f.add(new JLabel("Cdigo")); f.add(new JTextField(8)); f.add(new JLabel("Titular")); f.add(new JTextField(30)); f.add(new JLabel("Saldo")); f.add(new JTextField(8)); f.add(new JLabel("Inters")); f.add(new JTextField(4)); f.pack(); // Ajustar Frame a los contenidos f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }
Gestoresde distribucin

Programacinen GUIs

ElgestordedistribucinGridBagLayoutesun organizadorbasadotambinenrejillaaunquems flexible,concapacidadparaqueloscomponentes ocupenvariasceldasdedistintotamaosiesnecesario ElgestorSpringLayoutsebasaenlaespecificacinde distanciasentrelosbordesdelosdistintos componentes.Estpensadoparaelusodeuneditor grficointeractivo Tambin,aunqueestdesaconsejado,podemosanular elgestordedistribucinyeindicardirectamente posicionesytamaosparaloscomponentes

Gestoresde distribucin

Programacinen GUIs

staseralaformadeorganizarlaventanaprincipaldenuestroejemplode maneramanual
public class AppBanco { public static void main(String[] args) { JFrame f = new JFrame("Gestin de Cuentas"); JLabel lc, lt; JTextField tfc, tft; f.setLayout(null); f.add(lc = new JLabel("Cdigo")); f.add(tfc = new JTextField(8)); lc.setBounds(10, 10, 50, 20); tfc.setBounds(70, 10, 50, 20); f.add(lt = new JLabel("Titular")); f.add(tft = new JTextField(30)); lt.setLocation(10, 40); lt.setSize(50, 20); tft.setLocation(70, 40); tft.setSize(120, 20); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(320, 200); f.setVisible(true); } }
Gestoresde distribucin

Programacinen GUIs

Laorganizacinmanualomedianteungestorde distribucincomplejonicamenteresultaprctica medianteuneditorgrfico

Gestoresde distribucin

Programacinen GUIs

Aefectosprcticosseusanlamayoradelasveces FlowLayoutyBoxLayout,utilizandopanelesinternos paraagruparciertoscomponentes


VamosautilizartresJPanelparaagruparloscomponentesentresgrupos organizadosmedianteFlowLayout.Asuvezestostrespanelesvanaser controladosporunBoxLayout

(BoxLayoutY_AXIS) JPanelpc(FlowLayout) Cdigo JPanelpt(FlowLayout) Titular JPanelpsi(FlowLayout) Saldo Inters

Gestoresde distribucin

public class AppBanco { public static void main(String[] args) { JFrame f = new JFrame("Gestin de Cuentas"); JPanel pc = new JPanel(); pc.setLayout(new FlowLayout(FlowLayout.LEFT)); pc.add(new JLabel("Cdigo")); pc.add(new JTextField(8)); JPanel pt = new JPanel(); pt.setLayout(new FlowLayout(FlowLayout.LEFT)); pt.add(new JLabel("Titular")); pt.add(new JTextField(30)); JPanel psi = new JPanel(); psi.setLayout (new FlowLayout(FlowLayout.LEFT)); psi.add (new JLabel("Saldo")); psi.add (new JTextField(8)); psi.add (new JLabel("Inters")); psi.add (new JTextField(4)); f.setLayout ( new BoxLayout(f, BoxLayout.Y_AXIS)); f.add(pc); f.add(pt); f.add(psi); f.pack(); // Ajustar Frame a los contenidos f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }

Programacinen GUIs

Gestoresde distribucin

Programacinen GUIs

DiseandonuestroJFrame
CuandounJFrametieneciertacomplejidad,loms correctoyeleganteesextenderestaclaseaadiendo todaslascaractersticasquenecesitemos Elconstructorpuedeutilizarseparalacreacinde componentes,gestoresdedistribucin,etc. Loscomponentespuedenconectarseareferenciasque seanatributosparateneraccesoaellosenmltiples operacionesdelaclase
Elenfoqueutilizadohastaahoraennuestraaplicacinesvlidonicamentepara aplicacionesmuysimples.VamosadefinirunanuevaclaseFAppCuentaapartir deJFrame
public class AppBanco { public static void main(String[] args) { FAppBanco f = new FAppBanco(); } }

Diseandonuestro JFrame

import java.awt.*; import javax.swing.*; public class FAppBanco extends JFrame { JTextField tfc, tft, tfs, tfi; public FAppBanco() { super("Gestin de Cuentas Bancarias"); JPanel pc = new JPanel(); pc.setLayout(new FlowLayout(FlowLayout.LEFT)); pc.add(new JLabel("Cdigo")); pc.add(tfc = new JTextField(8)); JPanel pt = new JPanel(); pt.setLayout(new FlowLayout(FlowLayout.LEFT)); pt.add(new JLabel("Titular")); pt.add(tft = new JTextField(30)); JPanel psi = new JPanel(); psi.setLayout (new FlowLayout(FlowLayout.LEFT)); psi.add(new JLabel("Saldo")); psi.add(tfs = new JTextField (8)); tfs.setEditable(false); // Establecermos a slo lectura el saldo psi.add(new JLabel("Inters")); psi.add(tfi = new JTextField(4)); setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); add(pc); add(pt); add(psi); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } }

Programacinen GUIs

Diseandonuestro JFrame

Programacinen GUIs

UsaremosesteesquemaconlasclasesJFrame, JInternalFrameoJDialog,cuandocontenganunnmero relevantedecomponentesconunagestinmso menoscompleja,incluyendocapturayprocesamientode eventos Enestoscasoslanuevaclasedefinida,ademsdeser ensuncomponentedenuestrainterfaz,tieneuna segundafuncinmuyimportantedecoordinacin, gestinyprocesamientodelainformacinquellegaa travsdesuscomponenteshijos
Elenfoqueutilizadohastaahoraennuestraaplicacinesvlidonicamentepara aplicacionesmuysimples.VamosadefinirunanuevaclaseFAppCuentaapartir deJFrame
Diseandonuestro JFrame

Programacinen GUIs

Siguiendoconnuestroejemplo,vamosaaadirunatablaparaguardarlos movimientosrealizadosenlacuenta Loprimeroquehayquehacerescrearunaclaseespecialquevaasuministrarla informacinalatabla.ParaellopodemosimplementarlainterfazTableModelo extenderlaclaseAbstractTableModel,quetieneyaimplementacionespordefecto muchasdesusoperaciones ImplementaremosestaclasecomointeriordeFAppBanco


class InfoMovimientos extends AbstractTableModel { private final String[] nombreCols = { "Fecha", "Tipo", "Importe", "Saldo" }; // Devolver el ttulo de la columna indicada public String getColumnName(int column) { return nombreCols[column]; } // Devolver el nmero de columnas de la tabla public int getColumnCount() { return 4; } // Devolver nmero de filas de la tabla public int getRowCount() { return 0; // De momento, ninguna } // Devolver valor en la posicin (rowIndex, columnIndex) de la tabla public Object getValueAt(int rowIndex, int columnIndex) { return ""; // De momento, nada } } Diseandonuestro JFrame

Programacinen GUIs

NormalmentelatabladebeserinsertadaenunJScrollPane,yaqueencaso contrario,alaadirmuchasfilasiraalargandolaventanapaulatinamentehasta salirinclusodelapantalla Tambinvamosaaadirenlaparteinferiorcuatrobotonesparacrearuna cuenta,buscarunacuentayaexistente,realizarunaoperacinysalirdela aplicacin


class FAppBanco extends JFrame { JTextField tfc, tft, tfs, tfi; JButton bc, bb, bo, bs; // Nuevos atributos InfoMovimientos im; JTable tm; // Resto de la clase a partir de aqu... // Estamos en el constructor de FAppBanco... JPanel pm = new JPanel(); // Crear panel de la tabla pm.setLayout(new BorderLayout()); JLabel lm = new JLabel("Movimientos"); lm.setHorizontalAlignment(JLabel.CENTER); pm.add(lm, BorderLayout.NORTH); // Crear la tabla pasando un objeto de la clase InfoMovimientos tm = new JTable(im = new InfoMovimientos()); JScrollPane sp = new JScrollPane(tm); sp.setPreferredSize(400, 100); pm.add(sp, BorderLayout.CENTER);
Diseandonuestro JFrame

Programacinen GUIs

// Crear panel de botones JPanel pb = new JPanel(new FlowLayout(FlowLayout.CENTER)); pb.add(bc = new JButton("Crear")); pb.add(bb = new JButton("Buscar")); pb.add(bo = new JButton(Operar)); bo.setEnabled(false); // En principio el botn de operar est deshabilitado pb.add(bc = new JButton(Salir)); setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); add(pc); add(pt); add(psi); add(pm); // Aadir el panel de la tabla add(pb); // Aadir el panel de los botones pack(); setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); setVisible (true); } // Final del constructor de FAppBanco

Diseandonuestro JFrame

Programacinen GUIs

Capturadeeventos
Comovimosalprincipiodeltema,paralacapturade eventosSwingusaunesquemaasimilaraloscallbacks peroutilizandoclasesenlugardefunciones Cadaclasedecapturadeeventos(denominadosevent listeners)debeimplementarunainterfazconcretaen funcindeltipodeeventosquedeseacapturar Unavezimplementadoellistener,bastarconindicar stealcomponentedelcualdeseamoscapturarlos eventos

Capturadeeventos

Programacinen GUIs

Existenciertoseventlistenersquesoncomunesa todosloscomponentes:
FocusListener:capturaeventosrelacionadosconlarecepcinoprdidadelfoco KeyListener:capturapulsacionesdetecladosobreelcomponenteactivo MouseListener:capturalaentradaosalidadelcursorsobreuncomponente,as comopulsacionesdelosbotones MouseMotionListener:capturamovimientosdelratnsobreelcomponente

Otrossonespecficosdealgunoscomponentes:
ActionListener:capturaciertotipodeaccinrealizadasobreciertoscomponente. Porejemplo,pulsarunbotn,seleccionarunelementoenunalistadesplegableo unaopcinenunmen ChangeListener:registraloscambiossobreciertoscomponente.Porejemploun cambioeneldatodeunspinner,ounnuevovalorseleccionadoenunslider ItemListener:recogeelcambiodeestadoenuncomponentetipoon/off:check boxes,radiobuttonsylistasdesplegables ListSelectionListener:esunlistenerespecficoparadetectarlasselecciones mltiplesrealizadasenlistasytablas WindowListener:permiterecogerloseventosrelacionadosconlasventanas(cerrar, minimizar,maximizar,iconizar,etc.)enlosframes,framesinternosycuadrosde dilogo Capturadeeventos

Programacinen GUIs

Silainterfazcapturaunnicotipodeevento,como ActionListener,normalmentetendrunanicaoperacin aimplementar


voidactionPerformed(ActionEvente)

Encambioloslistenersmscomplejoscomo FocusListenerrequierenlaimplementacindevarias operaciones,cadaunaparauntipodeeventoconcreto


voidfocusGained(FocusEvente) voidfocusLost(FocusEvente)

Cuidado:unlistenerpuedetenerunsignificadodistinto dependiendodelcomponente(e.j.ActionListener) Informacindetalladadecadalistener:apartado ListenerssupportedbySwingComponentsdelTutorial JavadeSun


Capturadeeventos

Programacinen GUIs

ParalasinterfacesconmsdeunaoperacinSwing proporcionaporcomodidadunaclaseadaptadoraque implementalainterfazmedianteoperacionesvacas Cuandoslonecesitamosimplementarunaoperacin delainterfaz,extenderlaclaseadaptadoraesms cmodo Laclaseadaptadoracorrespondienteseobtiene sustituyendoListenerporAdapter


Ejemplo:WindowListener>WindowAdapter

Capturadeeventos

Programacinen GUIs

Haydosformasbsicasdeimplementarunlistener:
HacerqueelJFramequegeneraocontieneelcomponentegeneradordelevento seaunlistener,haciendoqueimplementelainterfazcorrespondiente(lomssimple yeficiente) Implementarunapequeaclaseinteriorquehagadelistener(lomsflexible)

Unavezimplementadoellistener,indicaremosal componentequeloutiliceparanotificarsuseventos mediantecomponente.add????Listener(objetoListener) donde????serelidentificadordeltipodelistener


VamosacapturareleventodepulsacindelbotnCrearyarealizarsu implementacin.Enprimerlugardeclararemoslaimplementacinde ActionListenerporpartedelaclaseFAppBanco.Tambinincluiremosunatributo paralacuentaactual
import java.awt.event.*; // Incluir las clases de eventos class FAppBanco extends JFrame implements ActionListener { Cuenta c; // Continua la implementacin de la clase FAppBanco...
Capturadeeventos

Programacinen GUIs

Acontinuacin,implementaremoslanicaoperacindeestainterfazyalgunas operacionesauxiliares
public void actionPerformed(ActionEvent e) { long codigo = comprobarCodigo(); if (codigo == -1) return; float interes = comprobarInteres(); if (interes == -1) return; salvarCuentaActual(); // Si existe una cuenta en memoria, salvarla if (existeCuenta(codigo)) { System.out.println(La cuenta ya existe !); return; } c = new Cuenta(codigo, tft.getText(), interes); // Crear cuenta tfs.setText("0.0"); // Por defecto el saldo a 0 inicialmente bo.setEnabled(true); // Activar botn de operaciones }

Capturadeeventos

private long comprobarCodigo() { long codigo; try { codigo = Long.parseLong(tfc.getText ()); if (codigo < 0) throw new NumberFormatException(); } catch(NumberFormatException nfe) { System.out.println("Error en cdigo de cuenta"); return -1; } return codigo; } private float comprobarInteres() { float interes; try { interes = Float.parseFloat(tfi.getText ()); if (interes < 0 || interes > 100) throw new NumberFormatException(); } catch(NumberFormatException nfe) { System.out.println("Error en el formato del inters"); return -1; } return interes; } public void salvarCuentaActual() { if (c == null) return; try { c.salvar(); } catch (IOException e) { System.out.println("Error al salvar cuenta"); } }

Programacinen GUIs

Capturadeeventos

Programacinen GUIs

FinalmenteindicaremosalbotnCrearqueenvieloseventosallistener
// Estamos en el constructor de FAppBanco... JPanel pb = new JPanel (new FlowLayout (FlowLayout.CENTER)); pb.add (bc = new JButton ("Crear")); bc.addActionListener (this); pb.add (bb = new JButton ("Buscar")); pb.add (bo = new JButton ("Operacin")); bo.setEnabled (false); pb.add (bs = new JButton ("Salir")); // Continua el constructor...

La implementacin mediante una clase interior sera la siguiente:


class FAppBanco extends JFrame { Cuenta c; JTextField tfc, tft, tfs, tfi; JButton bc, bb, bo, bs; // Nuevos atributos InfoMovimientos im; JTable tm; public class BotonCrearActionListener implements ActionListener { public void actionPerformed (ActionEvent e) { crearCuenta (); } } // Continua la clase FAppBanco a partir de aqu...
Capturadeeventos

Programacinen GUIs

LaoperacincrearCuenta()deFAppBancoincluiraelcdigodelacreacinde lacuenta(elmismoquelaantiguafuncinactionPerformed()deFAppBanco) Finalmenteconectaramoselbotnconellistener,creandounobjetodelaclase BotonCrearActionListener


// Estamos en el constructor de FAppBanco... JPanel pb = new JPanel (new FlowLayout (FlowLayout.CENTER)); pb.add (bc = new JButton ("Crear")); bc.addActionListener (new BotonCrearActionListener ()); pb.add (bb = new JButton ("Buscar")); pb.add (bo = new JButton ("Operacin")); bo.setEnabled (false); pb.add (bs = new JButton ("Salir")); // Continua el contructor...

No obstante, en nuestro ejemplo continuaremos siguiendo el primer mtodo

Capturadeeventos

Programacinen GUIs

Uncomponentepuedeserconectadoavarioslisteners delmismoodistintoseventos.Delamismaforma,un listenerpuedeserconectadoavarioscomponentesal mismotiempo Enestoscasosparadeterminardentrodellistenercul eselcomponentequehaenviadoeleventopodemos utilizarlaoperacingetSource()deleventorecibido Estasituacinesmuyfrecuentecuandolaclase principalhacedelistenerdelossubcomponentes


Vamos a incluir en la operacion actionPerformed() de FAppBanco el cdigo de procesamiento de los botones Crear, Buscar y Salir

Capturadeeventos

public void actionPerformed (ActionEvent e) { if (e.getSource () == bc) { // Botn Crear long codigo = comprobarCodigo (); if (codigo == -1) return; float interes = comprobarInteres (); if (interes == -1) return; salvarCuentaActual (); if (existeCuenta (codigo)) { System.out.println ("Ya existe una cuenta con ese cdigo"); return; } c = new Cuenta (codigo, tft.getText (), interes); tfs.setText ("0.0"); bo.setEnabled (true); } if (e.getSource () == bb) { // Botn Buscar long codigo = comprobarCodigo (); if (codigo == -1) return; try { c = new Cuenta (codigo); // Cargar la cuenta // Establecer los valores de la cuenta en los editores tfc.setText (new Long (codigo).toString ()); tft.setText (c.leerTitular ()); tfs.setText (new Float (c.leerSaldo ()).toString ()); tfi.setText (new Float (c.leerInteres ()).toString ()); im.fireTableDataChanged (); // Actualizar tabla bo.setEnabled (true); } catch (IOException ioe) { System.out.println ("La cuenta no existe"); } catch (ClassNotFoundException cnfe){} }

Programacinen GUIs

Capturadeeventos

Programacinen GUIs if (e.getSource () == bs) terminarAplicacion (); } private void terminarAplicacion () { salvarCuentaActual (); // Salvar cuenta actual antes de salir System.exit (0); }

VamosaincluirenlaoperacionactionPerformed()deFAppBancoelcdigode procesamientodelosbotonesCrear,BuscarySalir
class InfoMovimientos extends AbstractTableModel { private final String[] nombreCols = { "Fecha", "Tipo", "Importe", "Saldo" }; SimpleDateFormat sdf; public InfoMovimientos () { super (); // Crear un formateador de fechas sdf = new SimpleDateFormat ("dd.MM.yyyy } public String getColumnName (int column) { return nombreCols[column]; } public int getColumnCount() { return 4; } Capturadeeventos

HH:mm");

Programacinen GUIs

// Devolver nmero de elementos public int getRowCount() { if (c != null) return c.numMovimientosHistorico (); else return 0; } // Devolver el campo nmero columnIndex del elemento nmero rowIndex public Object getValueAt(int rowIndex, int columnIndex) { Movimiento m = c.leerMovimientoHistorico (rowIndex); switch (columnIndex) { case 0: return sdf.format (m.fecha); case 1: switch (m.tipo) { case 'I': return "ingreso"; case 'R': return "reintegro"; } case 2: return new Float (m.importe); case 3: return new Float (m.saldo); } return ""; // Aqu no se debera llegar ! } }

EstaclaseusadosoperacionesdelaclaseCuentanoexistentesenlaversininicial quevimoseneltema2:intnumMovimientosHistorico()yMovimiento leerMovimientoHistorico(intnm)


Capturadeeventos

Programacinen GUIs

Quedaunflecopendiente.SiterminamoslaaplicacinmedianteelbotnSalirla cuentaactualquedasalvadaendiscoautomticamenteantesdesalir.Sinembargo,si utilizamoselbotndecerrarlaventanalaaplicacinsecierradirectamentesinsalvarla cuenta Paraevitarestovamosacapturarloseventosrelacionadosconlaventanamediante unWindowListener.Enlugardeimplementartodalainferfaz,extendemoslaclase WindowAdapteryredefinimosnicamentelaoperacinquecapturaeleventodecierre delaventana.Estonosvaaobligarautilizarunaclaseinterior(porqu?)


// Estamos en el interior de la clase FAppBanco class FAppBancoWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { terminarAplicacion(); } } // Estamos en el interior del constructor de la clase FAppBanco // Anulamos esta instruccin // setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); // Y la sustituimos por una conexin al listener addWindowListener(new FAppBancoWindowListener());

Capturadeeventos

Programacinen GUIs

Conestonuestraaplicacinyaesutilizable.Podemoscargarunacuentaexistenteen discoocrearunanueva

Capturadeeventos

Programacinen GUIs

Cuadrosdedilogo
Loscuadrosdedilogosonventanasconunafuncin especfica
Notificaralusuariounerror,advertenciaoconsejo Pedirconfirmacinsobreunaoperacindeterminadaquesevaarealizar Obtenerlainformacinnecesariaparalarealizacindeunaoperacindeterminada

Unacapacidadespecialdeloscuadrosdedilogoesla debloquearlaaplicacindeformaqueelusuariono puedaseguirtrabajandohastaqueseatiendeasu peticin.Estetipodecuadrosdedilogosedenominan modales Elusomsfrecuentedeloscuadrosdedilogoeselde notificacinyconfirmacin.ParaestefinSwingcuenta concuadrosdedilogopredefinidos


Cuadrosdedilogo

Programacinen GUIs

Pararealizarunanotificacinutilizaremoslasiguiente operacin:JOptionPane.showDialog(<frameodilogo padre>,<mensaje>,<ttulo>,<tipo>) Eltipodemensajepuedeserdelossiguientestipos:


ERROR_MESSAGE INFORMATION_MESSAGE WARNING_MESSAGE QUESTION_MESSAGE PLAIN_MESSAGE

Estocrealoqueseconocecomomessageboxo cuadrodemensajemodal,conuniconoenfuncindel tipo

Cuadrosdedilogo

Programacinen GUIs

Parapedirunaconfirmacinutilizaremoslasiguiente operacin:JOptionPane.showConfirmDialog(<frameo dilogopadre>,<mensaje>,<ttulo>,<opciones>, <tipo>) Losparmetrossonsimilares.Elcampodeopciones puedetomarlosvalores


YES_NO_OPTION YES_NO_CANCEL_OPTION

Elvalorretornadoporestaoperacinesunenteroque indicaelbotnpulsado:
YES_OPTION NO_OPTION CANCEL_OPTION CLOSED_OPTION

Cuadrosdedilogo

Programacinen GUIs

Hastaahoraennuestraaplicacinlosmensajesdeerrorselanzabanalaconsola.Es horadecambiartodosestosmensajesporcuadrosdedilogo.Tambinvamosa introduciruncuadrodeconfirmacincuandoseintentacrearunacuentayaexistente


public void actionPerformed(ActionEvent e) { if (e.getSource() == bc) { long codigo = comprobarCodigo(); if (codigo == -1) return; float interes = comprobarInteres(); if (interes == -1) return; salvarCuentaActual(); if (existeCuenta(codigo)) if (JOptionPane.showConfirmDialog(this, "Ya existe una cuenta con ese cdigo. Desea sobreescribirla?", "Atencin", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) return; c = new Cuenta(codigo, tft.getText (), interes); tfs.setText("0.0"); bo.setEnabled(true); } // Sigue la implementacin del resto de la operacion...

Cuadrosdedilogo

Programacinen GUIs

private long comprobarCodigo() { long codigo; try { codigo = Long.parseLong(tfc.getText ()); if (codigo < 0) throw new NumberFormatException(); } catch (NumberFormatException nfe) { JOptionPane.showMessageDialog(this, "Cdigo de cuenta incorrecto", "Error", JOptionPane.ERROR_MESSAGE); return -1; } return codigo; } private float comprobarInteres() { float interes; try { interes = Float.parseFloat(tfi.getText ()); if (interes < 0 || interes > 100) throw new NumberFormatException(); } catch (NumberFormatException nfe) { JOptionPane.showMessageDialog(this, "Inters incorrecto. Debe ser un valor real entre 0 y 100", "Error", JOptionPane.ERROR_MESSAGE); return -1; } return interes; }

Cuadrosdedilogo

Programacinen GUIs

Laformamscomnderealizarunapeticinde informacinporpartedelusuarioesconstruiruncuadro dedilogoamedida,normalmentedetipomodal Laclasequerepresentauncuadrodedilogogenrico esJDialog.Aligualqueenelcasodelosframes, dependiendodelacomplejidaddelcuadroque necesitemospodremosconstruirlodirectamenteo utilizarextensinparaconstruiruncuadrodedilogo personalizado ElconstructordeJDialogeselsiguiente: JDialog(<frameodialogopadre>,<ttulo>,<modal?>)

Cuadrosdedilogo

Programacinen GUIs

CuandoelusuariopulseelbotnOperacinvamosapresentaruncuadrodedilogo quepidaelimporteyeltipodeoperacinarealizar.Vamosaconstruirestecuadrode dilogocomounaclasenuevahijadeJDialogdenominadaDOperacion


import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DOperacion extends JDialog implements ActionListener { JTextField tfi; JRadioButton rbi, rbr; JButton br, bc; // Importe de la operacin float importe; // Este atributo tendr valor true si los datos introducidos son correctos // y el usuario pulsa el botn Realizar boolean operar; public DOperacion(JFrame f) { super (f, "Realizar operacin", true); JPanel p = new JPanel(); p.setLayout (new FlowLayout()); JLabel l = new JLabel("Importe"); p.add(l); tfi = new JTextField(8); p.add (tfi); JPanel pto = new JPanel(); pto.setLayout (new FlowLayout()); Cuadrosdedilogo

Programacinen GUIs

Paraquelosradiobuttonsdeingresoyreintegroseanautoexcluyentesdebenser agrupadosutilizandounButtonGroup
rbi = new JRadioButton("Ingreso", true); rbr = new JRadioButton("Reintegro"); ButtonGroup bg = new ButtonGroup(); bg.add(rbi); // Aadir los dos botones al grupo bg.add(rbr); pto.add(rbi); pto.add(rbr); JPanel pb = new JPanel(); pb.add(br = new JButton("Realizar")); pb.add(bc = new JButton("Cancelar")); setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); add(p); add(pto); add(pb); pack(); // Capturar la pulsacin de los dos botones bc.addActionListener(this); br.addActionListener(this); operar = false; importe = 0; }

Cuadrosdedilogo

Programacinen GUIs

Capturamoslapulsacindelosdosbotones.AlpulsarRealizarcomprobaremossiel importeescorrectoyencasoafirmativodaremoselvistobuenoestableciendoel atributooperaratrue Parapoderobtenertodalainformacindesdeelframeprincipalhemosintroducido algunasoperacionesadicionales


public void actionPerformed(ActionEvent e) { if (e.getSource () == br) { try { importe = Float.parseFloat (tfi.getText ()); operar = true; hide (); } catch (NumberFormatException nfe) { JOptionPane.showMessageDialog (getContentPane (), "Importe incorrecto", "Error", JOptionPane.ERROR_MESSAGE); } } if (e.getSource () == bc) hide (); } public public public public } float leerImporte () { return importe; } boolean esIngreso () { return rbi.isSelected (); } boolean esReintegro () { return rbr.isSelected (); } boolean realizarOperacion () { return operar; }

Cuadrosdedilogo

Programacinen GUIs

SlofaltalanzarelcuadrodedilogocuandosepulseelbotndeOperacin.Para ellointroduciremoselsiguientecdigoenlaoperacinactionPerformed()deFAppBanco
// Estamos en actionPerformed de la clase FAppBanco if (e.getSource() == bo) { DOperacion d = new DOperacion(this); // Construir dilogo y mostrarlo d.setVisible(true); // Se ha pulsado el botn de realizar operacin? if (d.realizarOperacion()) { if (d.esIngreso()) c.ingreso(d.leerImporte()); else c.reintegro(d.leerImporte()); // Cambiar valor en el text field de saldo tfs.setText(new Float(c.leerSaldo()).toString()); // Indicar a la tabla que hemos aadido una fila, para que se actualice im.fireTableRowsInserted(c.numMovimientosHistorico() - 1, c.numMovimientosHistorico() - 1); } }

Cuadrosdedilogo

Programacinen GUIs

Teclasrpidas
Losusuariosqueutilizanhabitualmenteunaaplicacin suelenrequerirciertasrpidasparaagilizarsuuso Normalmenteunateclarpidasueleseruna combinacindeltipoALT+tecla Adems,debeayudarsealusuarioaidentificarestas teclasrpidasmarcandolateclaenelcomponenteen cuestin

Teclasrpidas

Programacinen GUIs

Enloscomponentesquetienenasociadaunaetiqueta, comobotones,opcionesdemens,etc.lateclarpida seestablecemediante componente.setMnemonic(<tecla>) Lasteclasvienenidentificadasmedianteunaseriede cdigosenlaclaseKeyEvent.Consultarlareferenciade estaclaseparaobtenerlalistacompletadecdigos Lasteclasnormalestienenasociadascdigossencillos. PorejemplolateclaKsecodificacomoVK_K Silateclaindicadatieneuncarcterasociadoyste apareceenlaetiquetadelcomponente,Swingse encargaderesaltarloautomticamente
Teclasrpidas

Programacinen GUIs

Existencomponentesquenotienenningunaetiqueta (p.e.JTextField).Siasociamosteclasaestos componentes,elusuarionotieneformadesabercules son Sinembargo,estoscomponentessuelentenerun JLabelparasuidentificacin.Podemosasociarlatecla alJLabeldelasiguientemanera: label.setLabelFor(textfield) label.setDisplayedMnemonic(<tecla>) DeestaformaelJLabelmuestralateclarpida,pero realmenteeseleditorelquelarecibe Resultaobviodecirquenodebenrepetirselasteclas rpidasdentrodeunframeodialog
Teclasrpidas

Programacinen GUIs

LateclaTABfuncionatambinautomticamentepara desplazarelfocodeuncomponenteaotro.Elordende visitadeloscomponentesvienedadoporelordende insercindestosenelpanel Enloscuadrosdedilogoesfrecuentequeexistaun botnpordefecto,queseactivapulsandolatecla RETURN.Estebotnapareceremarcadosobreelresto

Elbotnpordefectodelcuadrodedilogopuede indicarsedelasiguientemanera: dialogo.getRootPane().setDefaultButton(boton)


Teclasrpidas

Programacinen GUIs

Teniendoencuentaloanterior,aadirlasteclasrpidasanuestraaplicacinesuna cuestinrutinaria.Mostramosaqupartedelcdigomodificado
public FAppBanco() { super("Gestin de Cuentas Bancarias"); JLabel l; // Etiquetas y editores JPanel pc = new JPanel(); pc.setLayout(new FlowLayout(FlowLayout.LEFT)); pc.add(l = new JLabel("Cdigo")); pc.add(tfc = new JTextField(8)); l.setLabelFor(tfc); l.setDisplayedMnemonic(KeyEvent.VK_C); JPanel pt = new JPanel(); pt.setLayout(new FlowLayout(FlowLayout.LEFT)); pt.add(l = new JLabel("Titular")); pt.add(tft = new JTextField(30)); l.setLabelFor(tft); l.setDisplayedMnemonic(KeyEvent.VK_T); // Sigue el cdigo aqu... // Botones JPanel pb = new JPanel(new FlowLayout(FlowLayout.CENTER)); pb.add(bc = new JButton("Crear")); bc.setMnemonic(KeyEvent.VK_R); pb.add(bb = new JButton("Buscar")); bb.setMnemonic(KeyEvent.VK_B); pb.add(bo = new JButton("Operacin")); bo.setMnemonic(KeyEvent.VK_O); // Etc, etc... Teclasrpidas

Programacinen GUIs

LoslooksdeSwing
ParaterminarconnuestroejemployeltemadedicadoaprogramacinenGUIs podemosprobardistintoslooksparanuestraaplicacin
import javax.swing.UIManager; import javax.swing.JFrame; import javax.swing.JDialog; public class AppBanco { public AppBanco() { } public static void main(String[] args) { try { UIManager.setLookAndFeel(com.sun.java.swing.plaf.metal.MetalLookAndFeel"); //UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); //UIManager.setLookAndFeel(com.sun.java.swing.plaf.motif.MotifLookAndFeel"); } catch (Exception e) {} JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); FAppBanco f = new FAppBanco(); } } LoslooksdeSwing

Programacinen GUIs

LookMetal(pordefectoenJava1.4)

LookGTK

LookMotif

LoslooksdeSwing

Vous aimerez peut-être aussi