Está en la página 1de 0

LIDIA

Laboratorio de Investigacin y
desarrollo en Inteligencia Artificial
Departamento de Computacin
Universidade da Corua, Espaa
Principios de Anlisis Informtico
Tema 6: Fase de construccin
(Diseo del interfaz grfico del
usuario)
Eduardo Mosqueira Rey
2
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
ndice
1. Interfaces de usuario en Java
2. Principios de diseo de aplicaciones
grficas
3
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
ndice
1. Interfaces de usuario en Java
Introduccin
Operaciones bsicas
Gestores de composicin
Diseador de formularios de NetBeans
Gestin de eventos
4
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Introduccin
Relacin entre JFC, AWT y Swing
JFC (Java Foundation Classes)
Biblioteca de clases destinada a la creacin de interfaces de
usuario
Incluyen numerosos paquetes como Swing, AWT, Java2D,
Accessibility
Swing
Clases del JFC que se ocupan de la creacin de
componentes grficos
AWT
Incluye por motivos de compatibilidad los antiguos
componentes grficos del JDK 1.0 y 1.1.
Los componentes Swing slo han reemplazado la parte del
AWT en la que se definan los componentes GUI.
El resto de clases del AWT sigue siendo utilizado por otras
clases JFC
5
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
java.lang.Object
Container
Panel
java.applet.Applet
Button
Checkbox
CheckboxGroup
Choice
Label
List
Scrollbar
TextComponent
ScrollPane
Window
Dialog FileDialog
Component
Frame
TextArea
TextField
MenuComponent
MenuItem
CheckBoxMenuItem
Menu PopupMenu
MenuBar
java.awt
Interfaces de usuario en Java
Introduccin
AWT
6

AbstractButton
J DesktopPane
J Component
J ComboBox
J ColorChooser
J FileChooser
J InternalFrame
J Label
J LayeredPane
J List
J MenuBar
J OptionPane
J Panel
J PopupMenu
J ProgressBar
J RootPane
J ScrollBar
J ScrollPane
J Separator
J Slider
J SplitPane
J TabbedPane
J Table
J TableHeader
J TableHeader
J ToolBar
J ToolTip
J Tree
J Viewport
J Button
J MenuItem
J ToggleButton
J CheckBoxMenuItem
J RadioButtonMenu
J Menu
J CheckBox
J RadioButton
java.awt.Panel java.applet.Applet
java.awt.ScrollPane
java.awt.Window
java.awt.Dialog J Dialog
java.awt.Frame J Frame
J Window
java.awt.Container
J TextComponent
J EditorPane
J TextArea
J TextField
J TextPane
J PasswordField
J Applet
javax.swing
Box
Interfaces de usuario en Java
Introduccin
Swing
7
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Crear una ventana

i mpor t j avax. swi ng. *;

class Mi Fr ame extends J Fr ame
{
public Mi Fr ame( )
{
set Si ze( 200, 200) ;
set Ti t l e ( "Est a es mi f r ame") ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;
}
}

public class Fr amePr ueba
{
public static void mai n ( St r i ng [ ] ar gs)
{
Mi Fr ame f = new Mi Fr ame( ) ;
f . set Vi si bl e( t r ue) ;
}
}
Creamos una clase que herede de
JFrame y que en su constructor
incluya la informacin de
inicializacin de la ventana
Creamos una clase en cuyo main
se crea una instancia de MiFrame y
se llama a su mtodo setVisible
para mostrar la ventana por
pantalla.
Fijamos el comportamiento por
defecto de botn de cerrado
Interfaces de usuario en Java
Operaciones bsicas
8
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Inclusin de componentes

class Mi Fr ame extends J Fr ame
{
private J But t on b1 = new J But t on ( " Bot on 1" ) ,
b2 = new J But t on ( " Bot on 2" ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;

public Mi Fr ame( )
{
i ni t ( ) ;
pack( ) ;
}

public void i ni t ( )
{
set Ti t l e ( " T t ul o" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;

cont ent Pane. add( b1, Bor der Layout . WEST) ;
cont ent Pane. add( b2, Bor der Layout . EAST) ;
cont ent Pane. add( t , Bor der Layout . NORTH) ;
}
}
Creamos los componentes grficos
a la hora de definirlos
Obtenemos una referencia al
Content Pane o capa de contenidos
de la JFrame sobre la cual se van a
aadir los componentes (en AWT se
aadan sobre la propia Frame)
Aadimos los objetos al Content
Pane con el mtodo add. El primer
parmetro es siempre el
componente, el resto depende del
gestor de composicin (layout
manager)
(ver prximas transparencias)
Desde la versin 5 podemos hacer
this.add() sin necesidad de
obtener en Content Pane slo han
necesitado 7 aos para esta
modificacin!!
Interfaces de usuario en Java
Operaciones bsicas
9
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Capas de una JFrame Swing:
Root Pane
Layered Pane
Content Pane
Glass Pane
J Frame
Menu Bar
Interfaces de usuario en Java
Operaciones bsicas
10
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
Caractersticas principales
La posicin de los componentes en un contenedor vendr
definida por un gestor de composicin (layout manager).
En Java existe la posibilidad de no utilizar gestores de
composicin (lo que se denomina posicionamiento absoluto).
Sin embargo el uso de gestores de composicin se recomienda
ya que permite que el interfaz de usuario se adapte
automticamente a diversos cambios (en el tamao de las
ventanas, en el tamao de las fuentes, en la longitud de los
textos por cambio de idioma, etc.) lo cual genera interfaces ms
portables entre las distintas plataformas.
Para aadir un componente a un contenedor se utiliza el
mtodo add, que puede tomar diversas formas dependiendo del
gestor de composicin que se utilice.
11
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
Definicin de un gestor de composicin
Todo objeto de la clase Container tiene un mtodo setLayout
que le permite definir el gestor de composicin para ese
contenedor. La definicin de setLayout es:
public void setLayout (LayoutManager mgr)
Como todos los gestores de composicin implementan (directa
o indirectamente) el interfaz LayoutManager pueden pasarse
por parmetro a esta funcin.
Ejemplo :
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
Si quisiramos que el panel utilizara posicionamiento absoluto
simplemente habra que poner:
p.setLayout(null);
Gestores de composicin por defecto
BorderLayout en JFrame y JApplet; FlowLayout en JPanel
12
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
BorderLayout
Constructores:
Utilizacin:
Ejemplo:
Bor der Layout ( )
Bor der Layout ( i nt hgap, i nt vgap)
cont ent Pane. add( new J But t on( Bot on 1) , Bor der Layout . NORTH) ;
13
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
FlowLayout
Constructores:
Utilizacin:
Ejemplo:
publ i c Fl owLayout ( )
publ i c Fl owLayout ( i nt al i gnment )
publ i c Fl owLayout ( i nt al i gnment , i nt hgap, i nt vgap)
cont ent Pane. set Layout ( new Fl owLayout ( ) ) ;
cont ent Pane. add( b1) ;
cont ent Pane. add( b2) ;
14
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
GridLayout
Constructores:
Utilizacin:
Ejemplo:
publ i c Gr i dLayout ( )
publ i c Gr i dLayout ( i nt r ows, i nt col s)
publ i c Gr i dLayout ( i nt r ows, i nt col s, i nt hgap, i nt vgap)
cont ent Pane. set Layout ( new Gr i dLayout ( 2, 2) ) ;
cont ent Pane. add( new J But t on( Bot on 1) ) ;
cont ent Pane. add( new J Panel ( ) ) ;
cont ent Pane. add( new J Panel ( ) ) ;
cont ent Pane. add( new J But t on( Bot on 2) ) ;
15
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
GridBagLayout
J But t on b1 = new J But t on ( " Bot on 1" ) ,
b2 = new J But t on ( " Bot on 2" ) ,
b3 = new J But t on ( " Bot on 3" ) ,
b4 = new J But t on ( " Bot on 4" ) ,
b5 = new J But t on ( " Bot on 5" ) ;
Gr i dBagLayout GB = new Gr i dBagLayout ( ) ;
Gr i dBagConst r ai nt s c = new Gr i dBagConst r ai nt s( ) ;
cont ent Pane. set Layout ( GB) ;
c. f i l l = Gr i dBagConst r ai nt s. HORI ZONTAL;
c. wei ght x = 0. 5;
c. gr i dx = 0; / / Col oca el bot n en l a cel da ( 0, 0)
c. gr i dy = 0;
GB. set Const r ai nt s( b1, c) ;
cont ent Pane. add( b1) ;
c. gr i dx = 1; / / Col oca el bot n en l a cel da ( 1, 0)
c. gr i dy = 0;
GB. set Const r ai nt s( b2, c) ;
cont ent Pane. add( b2) ;
c. gr i dx = 2; / / Col oca el bot n en l a cel da ( 2, 0)
c. gr i dy = 0;
GB. set Const r ai nt s( b3, c) ;
cont ent Pane. add( b3) ;
c. gr i dx = 0; / / Col oca el bot n en l a cel da ( 0, 1)
c. gr i dy = 1;
c. i pady = 40; / / Hace que el component e sea ms al t o
c. wei ght x = 0. 0;
c. gr i dwi dt h = 3; / / Hacemos que t enga 3 cel das de ancho
GB. set Const r ai nt s( b4, c) ;
cont ent Pane. add( b4) ;
c. gr i dx = 1; / / Col oca el bot n en l a cel da ( 1, 2)
c. gr i dy = 2;
c. i pady = 0; / / Se r eset ea a su val or por def ect o
c. wei ght y = 1. 0; / / Ut i l i za el espaci o ver t i cal ext r a
c. anchor = Gr i dBagConst r ai nt s. SOUTH; / / Se f i j a al bor de i nf er i or
c. i nset s = new I nset s( 10, 0, 0, 0) ; / / I nt er val o super i or
c. gr i dwi dt h = 2; / / Hacemos que t enga 2 cel das de ancho
GB. set Const r ai nt s( b5, c) ;
cont ent Pane. add( b5) ;
16
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
GridBagLayout
Atri but o Valor por defecto Valores vli dos Especi fica
anchor CENTER CENTER
EAST
NORTH
NORTHEAST
NORTHWEST
SOUTH
SOUTHEAST
SOUTHWEST
WEST
Dnde fijar el componente dentro de la
rejilla de celdas
f i l l NONE BOTH
HORIZONTAL
VERTICAL
NONE
La manera en que el componente
rellena la celda que ocupa
gr i dx RELATI VE
gr i dy
RELATIVE o valores
enteros que representan
una posicin x, y en la
rejilla de celdas
La posicin de la celda superior
izquierda del componente
gr i dwi dt h 1
gr i dhei ght
RELATIVE, REMAINDER
o valores enteros que
representan el ancho y el
alto de las celdas de la
rejilla
El nmero de celdas en direccin
horizontal y vertical sobre las cuales se
dispone el componente. Si un
componente llena o no sus celdas
depende del atributo f i l l
i padx 0
i pady
Valores enteros que
representan el nmero de
pxeles
Intervalo interno que incrementa el
tamao predeterminado del
componente. Se aceptan valores
negativos que decrementan el tamao
del componente.
i nset s ( 0, 0, 0, 0) Un objeto de la clase
I nset s
Intervalo externo entre los lmites del
componente y los lmites de sus
celdas. Se aceptan valores negativos
que permiten que el componente se
extienda fuera de sus celdas
wei ght x 0. 0
wei ght y
Valores de tipo doubl e
que representan el peso
dado a las celdas del
componente de acuerdo a
otros componentes en la
misma fila o columna
Como el espacio extra es consumido
por las celdas del componente. Si un
componente llena o no sus celdas
depende del atributo f i l l s. Los
valores deben ser positivos
17
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
Paneles
anidados
J Frame con FlowLayout
J Panel con BorderLayout
J Panel con GridLayout
J Panel con GridLayout
18
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin

Cont ai ner cont ent Pane = get Cont ent Pane( ) ;
cont ent Pane. set Layout ( new Fl owLayout ( Fl owLayout . CENTER, 15, 15) ) ;

J Panel t ecl ado = new J Panel ( ) ;
t ecl ado. set Layout ( new Bor der Layout ( ) ) ;
t ecl ado. add( new J Text Fi el d( ) , Bor der Layout . NORTH) ;
J Panel bot oner a = new J Panel ( ) ;
bot oner a. set Layout ( new Gr i dLayout ( 4, 3) ) ;
bot oner a. add ( new J But t on ( "7") ) ;
bot oner a. add ( new J But t on ( "8") ) ;
bot oner a. add ( new J But t on ( "9") ) ;
bot oner a. add ( new J But t on ( "4") ) ;
bot oner a. add ( new J But t on ( "5") ) ;
bot oner a. add ( new J But t on ( "6") ) ;
bot oner a. add ( new J But t on ( "1") ) ;
bot oner a. add ( new J But t on ( "2") ) ;
bot oner a. add ( new J But t on ( "3") ) ;
bot oner a. add ( new J But t on ( "0") ) ;
bot oner a. add ( new J But t on ( ". ") ) ;
bot oner a. add ( new J But t on ( "CE" ) ) ;
t ecl ado. add( bot oner a, Bor der Layout . CENTER) ;

J Text Ar ea pant al l a = new J Text Ar ea( 4, 20) ;
pant al l a. set Text ( "Bi enveni do al Caj er o" ) ;

J Panel bot onesAcci on = new J Panel ( ) ;
bot onesAcci on. set Layout ( new Gr i dLayout ( 3, 1) ) ;
bot onesAcci on. add( new J But t on( " Acept ar " ) ) ;
bot onesAcci on. add( new J But t on( " Cancel ar ") ) ;
bot onesAcci on. add( new J But t on( " Bor r ar ") ) ;

cont ent Pane. add( t ecl ado) ;
cont ent Pane. add( pant al l a) ;
cont ent Pane. add( bot onesAcci on) ;
Paneles
anidados
19
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
GroupLayout
Incluido en la versin 6 del JDK
Ordena jerrquicamente los componentes en grupos.
Est orientado a ser usado por herramientas, pero
tambin puede codificarse a mano
Soporta dos tipos de grupos:
Secuenciales: los elementos de un grupo se posicionan
secuencialmente en un determinado eje, unos despus de
otros, tal y como hace el FlowLayout. La posicin de un
componente es relativa al componente que lo precede.
Paralelos: Los componentes se sitan en paralelo alineados
mediante un punto de referencia comn.
Generalmente los componentes situados en paralelo en una
dimensin estn situados en secuencia en la otra.
20
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestores de composicin
GroupLayout
Ejemplo
Pseudocdigo
horizontal layout =
sequential group {c1, c2, parallel group (LEFT) {c3,c4} }
vertical layout =
sequential group {parallel group (BASELINE) {c1, c2, c3}, c4}
21
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Diseador NetBeans
Para crear una ventana Java en NetBeans
slo hay que aadir una JFrame Form
bien desde el men contextual o desde el
men File New File
22
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
El diseador de formularios incluye dos
vistas: una vista grfica y otra vista del
cdigo fuente. La mayora de las acciones
se llevarn a cabo a travs de la vista
grfica
La paleta nos permite seleccionar los
componentes Swing que queremos aadir
a nuestra JFrame
El inspector nos muestra los
componentes de la JFrame de forma
jerrquica. Es muy til porque
visualmente a veces resulta complicado
dilucidar la estructura de los
componentes
Interfaces de usuario en Java
Diseador NetBeans
23
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Seleccionando un
componente en la paleta y
posteriormente pulsando
sobre la JFrame
aadiremos dicho
componente a la ventana
El inspector de
propiedades permite
modificar las propiedades
de cada componente
grfico
Interfaces de usuario en Java
Diseador NetBeans
24
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
A travs del inspector podemos
modificar el layout por defecto de la
JFrame
Interfaces de usuario en Java
Diseador NetBeans
25
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
En todo momento podemos ver el cdigo
generado pulsando en source . Este cdigo
es 100% Java por lo que puede usarse
perfectamente fuera de NetBeans
El cdigo marcado en
azul es gestionado por
NetBeans, por lo que
no puede ser
modificado si
queremos que el
diseador de
formularios funcione
correctamente
Como vemos NetBeans
utiliza la estrategia de
clases internas
annimas con
rellamadas a mtodos
privados para gestionar
los eventos
Interfaces de usuario en Java
Diseador NetBeans
26
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Desde la versin 5.0 de NetBeans incorpora un nuevo
diseador de formularios denominado Matisse que se
caracteriza por:
Permite crear formularios profesionales con poco
conocimiento de Swing
Los componentes se posicionan mediante drag&drop y se
agrupan para reaccionar a los cambios de los componentes
vecinos
Introduce un nuevo LayoutManager (GroupLayout) incluido
en el JDK desde la versin 6
Ver demo en:
http://www.netbeans.org/files/documents/4/475/matisse.html
Interfaces de usuario en Java
Diseador NetBeans
27
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestin de eventos
Modelo de delegacin
El modelo de eventos basado en la delegacin recibe su
nombre del hecho de que la gestin de eventos es delegada
desde una fuente de eventos a una serie de objetos que actan
como escuchadores de ese evento y que reaccionan a su
ocurrencia.
El modelo gira en torno a tres tipos de objetos
Fuentes de eventos:
que se encargan de disparar dichos eventos.
Escuchadores de eventos:
que tratan los eventos disparados por las fuentes.
Eventos:
Se encargan de representar al evento disparado y contienen
informacin sobre el mismo.
28
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Interfaces de usuario en Java
Gestin de eventos
Fuente del
evento
Objeto que
representa al
evento
Escuchador
del evento
registrado
Escuchador
del evento
registrado
Escuchador
del evento
registrado
Interfaz del
evento
Implementan
Elementos bsicos del modelo de delegacin
29
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Gestin de Eventos
Pasos para gestionar un evento
Creamos una clase que implemente el interfaz XYZListener, donde
XYZ es el evento que queremos escuchar.
Implementar el interfaz XYZListener va a significar que debemos dar
implementacin a una serie de mtodos predefinidos para la gestin
del evento. Estos mtodos aceptarn siempre como parmetro una
instancia de la clase XYZEvent.
Registramos un objeto de la clase que implementa XYZListener
como escuchador del generador del evento (el botn).
Este registro se realiza mediante el mtodo addXYZListener el cual
acepta como parmetro una instancia de una clase que implemente el
interfaz XYZListener.
Cuando el evento sucede el generador del evento llama a un
mtodo determinado de todos los objetos del tipo XYZListener que
se han registrado como escuchadores de ese evento mediante el
mtodo add.
El mtodo llamado incluir como parmetro una instancia de la clase
XYZEvent.
30
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
class B1 implements Act i onLi st ener
{ private J Text Fi el d t ;
public B1( J Text Fi el d t )
{ this. t = t ; }
public void actionPerformed ( Act i onEvent e)
{ t . setText( " Has pul sado el bot on 1" ) ; }
}
class B2 implements Act i onLi st ener
{ private J Text Fi el d t ;
public B2( J Text Fi el d t )
{ this. t = t ; }
public void actionPerformed ( Act i onEvent e)
{ t . setText( " Has pul sado el bot on 2" ) ; }
}
import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;
class Fr ameEvent os
{ public static void mai n ( St r i ng [ ] ar gs)
{ Mi Fr ame f = new Mi Fr ame( ) ;
f . set Vi si bl e( true) ;
}
}
class Mi Fr ame extends J Fr ame
{ private J But t on b1 = new J But t on ( " Bot on 1" ) ,
b2 = new J But t on ( " Bot on 2" ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;
public Mi Fr ame( )
{ i ni t ( ) ;
pack( ) ;
}
public void i ni t ( )
{ set Ti t l e ( " T t ul o" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;
cont ent Pane. add( b1, Bor der Layout . WEST) ;
cont ent Pane. add( b2, Bor der Layout . EAST) ;
cont ent Pane. add( t , Bor der Layout . NORTH) ;
b1. addActionListener( new B1( t ) ) ;
b2. addActionListener( new B2( t ) ) ;
}
}
Gestin de Eventos
Pasos para gestionar un evento
Con clases externas
Fijamos como escuchador
del botn b1 un objeto
annimo (sin nombre) de la
clase B1
Las clases B1 y B2 tienen
un mtodo actionPerformed
que es llamado por los
botones b1 y b2
respectivamente cuando
son pulsados (evento
Action)
Como B1 es independiente
de MiFrame es necesario
pasar el JTextField por
parmetro
31
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
public void init ( )
{ setTitle ( " T t ul o" ) ;
setDefaultCloseOperation( EXI T_ON_CLOSE) ;
cont ent Pane. add( b1, Bor der Layout . WEST) ;
cont ent Pane. add( b2, Bor der Layout . EAST) ;
cont ent Pane. add( t , Bor der Layout . NORTH) ;
b1. addActionListener( new B1( ) ) ;
b2. addActionListener( new B2( ) ) ;
}
class B1 implements Act i onLi st ener
{ public void actionPerformed ( Act i onEvent e)
{ t . setText( " Has pul sado el bot on 1" ) ; }
}
class B2 implements Act i onLi st ener
{ public void actionPerformed ( Act i onEvent e)
{ t . setText( " Has pul sado el bot on 2" ) ; }
}
}
import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;
class Fr ameEvent os
{
public static void main ( St r i ng [ ] ar gs)
{
Mi Fr ame f = new MiFrame( ) ;
f . setVisible( true) ;
}
}
class Mi Fr ame extends J Fr ame
{
private J But t on b1 = new JButton ( " Bot on 1" ) ;
private J But t on b2 = new JButton ( " Bot on 2" ) ;
private J Text Fi el d t = new JTextField( 20) ;
Cont ai ner cont ent Pane = getContentPane( ) ;
public MiFrame( )
{ init( ) ;
pack( ) ;
}
Gestin de Eventos
Pasos para gestionar un evento
Con clases internas
Las clases B1 y B2 se definen
dentro de la clase MiFrame
Como elementos internos
de MiFrame pueden ver sus
atributos privados (por
ejemplo el JTextField t)
32
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
/ / . . .
public void init ( )
{
setTitle ( " T t ul o" ) ;
setDefaultCloseOperation( EXI T_ON_CLOSE) ;
cont ent Pane. add( b1, BorderLayout. WEST) ;
contentPane. add( b2, Bor der Layout . EAST) ;
cont ent Pane. add( t , Bor der Layout . NORTH) ;
b1. addActionListener( new ActionListener( )
{ public void actionPerformed ( ActionEvent e)
{ t . setText( "Has pul sado el bot on 1" ) ; }
}
) ;
b2. addAct i onLi st ener ( new ActionListener( )
{ public void actionPerformed ( ActionEvent e)
{ t . setText( "Has pul sado el bot on 2" ) ; }
}
) ;
}
/ / . . .
Gestin de Eventos
Pasos para gestionar un evento
Con clases internas annimas
Se definen clases internas annimas en
el mismo instante en que se crea un
objeto de dicha clase. Eso evita tener
que definir un nombre para una clase
que slo se usa una vez (B1)
Despus del new se especifica el
nombre de la clase o interfaz del que
hereda la clase interna annima
Cuerpo de la clase
Finaliza la llamada al mtodo
addActionListener
33
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
/ / . . .
private void modificaTexto ( St r i ng cadena)
{
t . setText( cadena) ;
}
public void init ( )
{
setTitle ( " T t ul o" ) ;
setDefaultCloseOperation( EXI T_ON_CLOSE) ;
cont ent Pane. add( b1, Bor der Layout . WEST) ;
cont ent Pane. add( b2, Bor der Layout . EAST) ;
cont ent Pane. add( t , Bor der Layout . NORTH) ;
b1. addActionListener( new ActionListener( )
{ public void actionPerformed ( Act i onEvent e)
{ modificaTexto( " Has pul sado el bot on 1" ) ; }
}) ;
b2. addActionListener( new ActionListener( )
{ public void actionPerformed ( Act i onEvent e)
{ modificaTexto( " Has pul sado el bot on 2" ) ; }
}) ;
}
/ / . . .
Gestin de Eventos
Pasos para gestionar un evento
Con clases internas annimas con rellamadas a
mtodos privados de la clase externa
El mtodo actionPerformed de la clase interna
annima no realiza el trabajo sino que lo delega
en un mtodo de su clase envoltorio (en este
caso modificaTexto de la clase MiFrame)
La clase interna annima acta como un
adaptador que evita que la clase MiFrame tenga
que implementar el interfaz ActionListener
34
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
ndice
2. Principios de diseo de aplicaciones
grficas
Introduccin
Separacin interfaz-lgica aplicacin
Patrn Modelo-Vista-Controlador
35
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Introduccin
Partes de una aplicacin
Interfaz de usuario
Interacciona con el usuario
Gestiona la informacin introducida por los dispositivos de entrada
y muestra los resultados por los dispositivos de salida
Lgica de la aplicacin
Procesa la informacin de entrada para generar los resultados que
se persiguen.
Es el elemento fundamental que diferencia a unas aplicaciones de
otras
Se le suele llamar lgica del negocio o empresarial porque contiene
las reglas que controlan las actividades propias de la empresa
(gestin de pedidos, control de inventario, etc.)
Servicios
Ofrece servicios que necesitan otros niveles: servicios de bases de
datos (los ms comunes), de archivo, de comunicacin, de
impresin, etc.
36
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Introduccin
Principios de diseo
Las distintas partes que forman una aplicacin
deben mantenerse desligadas unas de otras
Eso permite que cambios en una parte no afecten a
las otras partes
Tambin permite sustituir por completo una parte
afectando mnimamente a las otras
La orientacin a objetos en general y Java en
particular fomenta la separacin lgica entre las
distintas partes que forman una aplicacin
37
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Separacin interfaz-lgica aplicacin
Problemas de interfaz y lgica no desligados
Al relacionar intrnsicamente interfaz y lgica, la adaptacin
de la aplicacin a otro tipo de interfaz (Web, PDA, etc.) no es
sencilla.
El interfaz del sistema suele cambiar con frecuencia debido a
peticiones o sugerencias del usuario, o debido a que se
aaden nuevas capacidades.
Para adaptarse a los cambios el interfaz del usuario tiene que
ser flexible, la mejor manera de conseguir flexibilidad es
desligando al propio sistema de su interfaz.
Si la lgica y el interfaz no estn separados no es fcil
determinar con precisin si los errores son de la interfaz de
usuario o del sistema
38
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Separacin interfaz-lgica aplicacin
Cuenta NO desligada

import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;

class GUI Cuent a extends J Fr ame
{
private int sal do=0;
private J Label l abel Sal do = new J Label ( " Sal do : " ) ;
private J Label l abel Cant i dad = new J Label ( " 0" ) ;
private J But t on bI ngr esar = new J But t on ( " I ngr esar " ) ,
bRet i r ar = new J But t on ( " Ret i r ar " ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;

public GUI Cuent a( )
{
i ni t ( ) ;
pack( ) ;
}

public void i ni t ( )
{
set Ti t l e ( " Cuent a no desl i gada" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;

J Panel panel Bot ones = new J Panel ( new Gr i dLayout ( 1, 2) ) ;
J Panel panel Sal do = new J Panel ( ) ;
panel Bot ones. add( bI ngr esar ) ;
panel Bot ones. add( bRet i r ar ) ;
panel Sal do. add( l abel Sal do) ;
panel Sal do. add( l abel Cant i dad) ;
cont ent Pane. add( panel Sal do, Bor der Layout . NORTH) ;
cont ent Pane. add( t , Bor der Layout . CENTER) ;
cont ent Pane. add( panel Bot ones, Bor der Layout . SOUTH) ;


bI ngr esar . addAct i onLi st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
i ngr esar ( cant i dad) ;
l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( sal do) ) ;
}
}
) ;

bRet i r ar . addAct i onLi st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
r et i r ar ( cant i dad) ;
l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( sal do) ) ;
}
}
) ;
}

public void i ngr esar ( int cant i dad)
{ sal do = sal do + cant i dad; }

public void r et i r ar ( int cant i dad)
{ if ( cant i dad < sal do)
sal do = sal do - cant i dad;
else sal do = 0;
}
}

class Cuent aNoDesl i gada
{ public static void mai n ( St r i ng [ ] ar gs)
{ GUI Cuent a f = new GUI Cuent a( ) ;
f . show( ) ;
}
}
El funcionamiento del GUI y
de la cuenta se sita en la
misma clase
39
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Separacin interfaz-lgica aplicacin
Principios para desligar lgica e interfaz
Limitacin en el conocimiento mutuo
La lgica NO debe conocer a qu interfaz de usuario est
sirviendo (puede estar sirviendo a varios a la vez)
El interfaz de usuario s puede conocer sobre qu lgica
acta
La lgica puede notificar cambios en su estado a sus
interfaces asociados (aunque no debe conocer con que
clase exacta est trabajando) patrn observador
Situacin de las reglas del dominio
Es muy importante que las reglas del dominio se siten en la
lgica y no en el interfaz (p. ej. no se puede sacar ms
dinero de una cuenta que el disponible en el saldo)
Si las reglas del dominio se filtran al interfaz cada vez que se
crea un nuevo interfaz hay que acordarse de mantener las
reglas confusin de responsabilidades
40
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Separacin interfaz-lgica aplicacin
Cuenta Desligada

import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;

class GUI Cuent a extends J Fr ame
{
private Cuent a mi Cuent a = new Cuent a( 0) ;
private J Label l abel Sal do = new J Label ( " Sal do : " ) ;
private J Label l abel Cant i dad = new J Label ( " 0" ) ;
private J But t on bI ngr esar = new J But t on ( " I ngr esar " ) ,
bRet i r ar = new J But t on ( " Ret i r ar " ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;

public GUI Cuent a( )
{ i ni t ( ) ;
pack( ) ;
}

public void i ni t ( )
{
set Ti t l e ( " Cuent a Desl i gada" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;

J Panel panel Bot ones = new J Panel ( new Gr i dLayout ( 1, 2) ) ;
J Panel panel Sal do = new J Panel ( ) ;
panel Bot ones. add( bI ngr esar ) ;
panel Bot ones. add( bRet i r ar ) ;
panel Sal do. add( l abel Sal do) ;
panel Sal do. add( l abel Cant i dad) ;
cont ent Pane. add( panel Sal do, Bor der Layout . NORTH) ;
cont ent Pane. add( t , Bor der Layout . CENTER) ;
cont ent Pane. add( panel Bot ones, Bor der Layout . SOUTH) ;

bI ngr esar . addAct i onLi st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
mi Cuent a. i ngr esar ( cant i dad) ;
l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( mi Cuent a. get Sal do( ) ) ) ;
}
}
) ;
bRet i r ar . addAct i onLi st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
mi Cuent a. r et i r ar ( cant i dad) ;
l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( mi Cuent a. get Sal do( ) ) ) ;
}
}
) ;
}
}

class Cuent a
{
private int sal do;

public Cuent a ( int sal do)
{ this. sal do = sal do; }

public int get Sal do( )
{ return sal do; }

public void i ngr esar ( int cant i dad)
{ sal do = sal do + cant i dad; }

public void r et i r ar ( int cant i dad)
{ if ( cant i dad < sal do)
sal do = sal do - cant i dad;
else sal do = 0;
}
}

class Cuent aDesl i gada
{ public static void mai n ( St r i ng [ ] ar gs)
{ GUI Cuent a f = new GUI Cuent a( ) ;
f . set Vi si bl e( true) ;
}
}
El GUI guarda una referencia a
una cuenta interna
El GUI y la cuenta son
clases separadas, adems la
cuenta no sabe qu GUI la
utiliza
La cuenta no se comunica con el
GUI por lo que tiene que ser este
ltimo el encargado de actualizarse
cuando se produce un cambio
41
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Separacin interfaz-lgica aplicacin
Cuenta Desligada con notificacin
import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;

interface Obser ver
{ public void updat e( ) ; }

class GUI Cuent a extends J Fr ame implements Obser ver
{
private Cuent a mi Cuent a = new Cuent a( 0) ;
private J Label l abel Sal do = new J Label ( " Sal do : " ) ;
private J Label l abel Cant i dad = new J Label ( " 0" ) ;
private J But t on bI ngr esar = new J But t on ( " I ngr esar " ) ,
bRet i r ar = new J But t on ( " Ret i r ar " ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;

public GUI Cuent a( )
{ mi Cuent a. set Obser vador ( this) ;
i ni t ( ) ;
pack( ) ;
}

public void i ni t ( )
{ set Ti t l e ( " Cuent a Desl i gada 2" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;

J Panel panel Bot ones = new J Panel ( new Gr i dLayout ( 1, 2) ) ;
J Panel panel Sal do = new J Panel ( ) ;
panel Bot ones. add( bI ngr esar ) ;
panel Bot ones. add( bRet i r ar ) ;
panel Sal do. add( l abel Sal do) ;
panel Sal do. add( l abel Cant i dad) ;
cont ent Pane. add( panel Sal do, Bor der Layout . NORTH) ;
cont ent Pane. add( t , Bor der Layout . CENTER) ;
cont ent Pane. add( panel Bot ones, Bor der Layout . SOUTH) ;

bI ngr esar . addAct i onLi st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
mi Cuent a. i ngr esar ( cant i dad) ;
}
}
) ;
bRet i r ar . addAct i onLi st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
mi Cuent a. r et i r ar ( cant i dad) ;
}
}
) ;
}
public void updat e( )
{ l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( mi Cuent a. get Sal do( ) ) ) ; }
}

class Cuent a
{ private int sal do;
private Obser ver i nt er f az;

public Cuent a ( int sal do)
{ this. sal do = sal do; }

public void set Obser vador ( Obser ver o)
{ i nt er f az=o; }

public int get Sal do( )
{ return sal do; }

public void i ngr esar ( int cant i dad)
{ sal do = sal do + cant i dad;
i nt er f az. updat e( ) ;
}

public void r et i r ar ( int cant i dad)
{ if ( cant i dad < sal do) sal do = sal do - cant i dad;
else sal do = 0;
i nt er f az. updat e( ) ;
}
}

class Cuent aDesl i gada2
{ public static void mai n ( St r i ng [ ] ar gs)
{ GUI Cuent a f = new GUI Cuent a( ) ;
f . set Vi si bl e( true) ;
}
}
Creamos un interfaz para
comunicar la cuenta con el GUI
La cuenta mantiene una
referencia a su observador
pero no conoce su clase
concreta (solo sabe que
implementa el interfaz
Observer)
El mtodo update ser llamado cuando se
produzca algn cambio en la cuenta
El GUI se registra como
observador de la cuenta
El GUI no se preocupa de
actualizarse al modificar la cuenta
Cuando la cuenta se
modifica se acuerda de
avisar al GUI que la est
observando
42
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Separacin interfaz-lgica aplicacin
Cuenta Desligada con notificacin mltiple

import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;
import j ava. ut i l . *;


interface Obser ver
{ public void updat e( ) ; }


class GUI Cuent a extends J Fr ame implements Obser ver
{
private Cuent a mi Cuent a;
private J Label l abel Sal do = new J Label ( " Sal do : " ) ;
private J Label l abel Cant i dad = new J Label ( " 0" ) ;
private J But t on bI ngr esar = new J But t on( " I ngr esar " ) ,
bRet i r ar = new J But t on( " Ret i r ar " ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;

public GUI Cuent a( Cuent a c)
{
mi Cuent a=c;
mi Cuent a. r egi st r ar Obser vador ( this) ;
i ni t ( ) ;
pack( ) ;
}

public void updat e( )
{ l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( mi Cuent a. get Sal do( ) ) ) ; }
public void i ni t ( )
{
set Ti t l e( " Cuent a Desl i gada 3" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;

J Panel panel Bot ones = new J Panel ( new Gr i dLayout ( 1, 2) ) ;
J Panel panel Sal do = new J Panel ( ) ;
panel Bot ones. add( bI ngr esar ) ;
panel Bot ones. add( bRet i r ar ) ;
panel Sal do. add( l abel Sal do) ;
panel Sal do. add( l abel Cant i dad) ;
cont ent Pane. add( panel Sal do, Bor der Layout . NORTH) ;
cont ent Pane. add( t , Bor der Layout . CENTER) ;
cont ent Pane. add( panel Bot ones, Bor der Layout . SOUTH) ;

bI ngr esar . addAct i onLi st ener ( new Act i onLi st ener ( )
{
public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
mi Cuent a. i ngr esar ( cant i dad) ;
}
}
) ;

bRet i r ar . addAct i onLi st ener ( new Act i onLi st ener ( )
{
public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = I nt eger . par seI nt ( t . get Text ( ) ) ;
mi Cuent a. r et i r ar ( cant i dad) ;
}
}
) ;
}
}
La cuenta ya no es algo
interno al GUI sino que se pasa
por parmetro al constructor
El GUI se registra como
observador de la cuenta
43
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Separacin interfaz-lgica aplicacin
Cuenta Desligada con notificacin mltiple (cont.)

class Cuent a
{ private int sal do;
private Ar r ayLi st escuchador es = new Ar r ayLi st ( ) ;

public Cuent a( int sal do)
{ this. sal do = sal do; }

public int get Sal do( )
{ return sal do; }

public void i ngr esar ( int cant i dad)
{ sal do = sal do + cant i dad;
act ual i zar Obser vador es( ) ;
}

public void r et i r ar ( int cant i dad)
{
if ( cant i dad < sal do) sal do = sal do - cant i dad;
else sal do = 0;
act ual i zar Obser vador es( ) ;
}

public void r egi st r ar Obser vador ( Obser ver o)
{
escuchador es. add( o) ;
o. updat e( ) ;
}

public void el i mi nar Obser vador ( Obser ver o)
{ escuchador es. r emove( o) ; }

private void act ual i zar Obser vador es( )
{
I t er at or i = escuchador es. i t er at or ( ) ;
while( i . hasNext ( ) )
{ Obser ver o = ( Obser ver ) i . next ( ) ;
o. updat e( ) ;
}
}
}
class GUI Cuent aText o implements Obser ver
{
private Cuent a mi Cuent a;

public GUI Cuent aText o( Cuent a c)
{
mi Cuent a=c;
mi Cuent a. r egi st r ar Obser vador ( this) ;
}

public void updat e( )
{
Syst em. out . pr i nt l n( "Sal do act ual : " + mi Cuent a. get Sal do( ) + " " ) ;
}
}


class Cuent aDesl i gada3
{
public static void mai n( St r i ng [ ] ar gs)
{
Cuent a c = new Cuent a( 0) ;
GUI Cuent a f = new GUI Cuent a( c) ;
GUI Cuent aText o t = new GUI Cuent aText o( c) ;
f . set Vi si bl e( true) ;
}
}
La cuenta mantiene una
lista de observadores
Cuando se produce un cambio se
notifica a todos los observadores
registrados en la lista
Se incluyen mtodos para
aadir y borrar observadores
Esta clase representa un nuevo
interfaz para la cuenta (aunque
no interactivo)
Debe registrarse como
observador e implementar
update
La cuenta es un objeto
independiente de sus
escuchadores
44
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Separacin interfaz-lgica aplicacin
Cuenta Desligada con notificacin mltiple (cont.)
45
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Caractersticas
Patrn arquitectnico que define el diseo de interfaces de usuario desligadas
del sistema subyacente
Se populariz con el lenguaje Smalltalk y hoy en da es la tcnica habitual de
diseo de interfaces en la programacin Web con J2EE
Componentes
Modelo
Abstraccin que representa a los objetos de la aplicacin propiamente dicha,
incluyendo sus datos y comportamiento pero no su interfaz de usuario
Incluye mtodos de acceso para la lectura y modificacin de dichos datos
Se encarga de notificar a la vista los cambios que se producen
Vista
Representacin visual de los datos del modelo
Necesita acceder al modelo para obtener los datos a representar
Controlador
Recoge los eventos producidos por el usuario sobre la vista
Invoca las acciones necesarias sobre el modelo
Generalmente es el nico conoce a las otras dos partes (el modelo no conoce a las
otras partes y la vista no conoce a su controlador y puede no conocer al modelo)
46
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
47
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
48
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
49
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
50
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Modelo
No cambia con respecto a lo visto en transparencias anteriores
Vista
import j avax. swi ng. *;
import j ava. awt . *;
import j ava. awt . event . *;
import j ava. ut i l . *;

class GUI Cuent a extends J Fr ame implements Obser ver
{ private Cuent a mi Cuent a;
private J Label l abel Sal do = new J Label ( " Sal do : " ) ;
private J Label l abel Cant i dad = new J Label ( " 0" ) ;
private J But t on bI ngr esar = new J But t on( " I ngr esar " ) ,
bRet i r ar = new J But t on( " Ret i r ar " ) ;
private J Text Fi el d t = new J Text Fi el d( 20) ;
Cont ai ner cont ent Pane = get Cont ent Pane( ) ;

public GUI Cuent a( Cuent a c)
{ mi Cuent a=c;
mi Cuent a. r egi st r ar Obser vador ( this) ;
i ni t ( ) ;
pack( ) ;
}
public void updat e( )
{ l abel Cant i dad. set Text ( I nt eger . t oSt r i ng( mi Cuent a. get Sal do( ) ) ) ; }

public void i ni t ( )
{ set Ti t l e( " Cuent a Desl i gada 3" ) ;
set Def aul t Cl oseOper at i on( EXI T_ON_CLOSE) ;

J Panel panel Bot ones = new J Panel ( new Gr i dLayout ( 1, 2) ) ;
J Panel panel Sal do = new J Panel ( ) ;
panel Bot ones. add( bI ngr esar ) ;
panel Bot ones. add( bRet i r ar ) ;
panel Sal do. add( l abel Sal do) ;
panel Sal do. add( l abel Cant i dad) ;
cont ent Pane. add( panel Sal do, Bor der Layout . NORTH) ;
cont ent Pane. add( t , Bor der Layout . CENTER) ;
cont ent Pane. add( panel Bot ones, Bor der Layout . SOUTH) ;
}

public void set I ngr esar Li st ener ( Act i onLi st ener al )
{ bI ngr esar . addAct i onLi st ener ( al ) ; }

public void set Ret i r ar Li st ener ( Act i onLi st ener al )
{ bRet i r ar . addAct i onLi st ener ( al ) ; }

public int get Sal do( )
{ return I nt eger . par seI nt ( t . get Text ( ) ) ; }
}
La vista ofrece mtodos
para actualizar los
escuchadores de
eventos producidos por
el usuario
La vista ofrece mtodos para
acceder a sus atributos
privados
51
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Controlador

class Cont r ol ador Cuent a
{
Cuent a model o;
GUI Cuent a vi st a;

Cont r ol ador Cuent a( Cuent a m, GUI Cuent a v)
{
model o = m;
vi st a = v;

model o. r egi st r ar Obser vador ( vi st a) ;

vi st a. set I ngr esar Li st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = vi st a. get Sal do( ) ;
model o. i ngr esar ( cant i dad) ;
}
}
) ;

vi st a. set Ret i r ar Li st ener ( new Act i onLi st ener ( )
{ public void act i onPer f or med( Act i onEvent e)
{ int cant i dad = vi st a. get Sal do( ) ;
model o. r et i r ar ( cant i dad) ;
}
}
) ;
}
}
class Cuent aMVC
{
public static void mai n( St r i ng [ ] ar gs)
{
Cuent a model o = new Cuent a( 0) ;
GUI Cuent a vi st a = new GUI Cuent a( model o) ;
Cont r ol ador Cuent a ct r = new Cont r ol ador Cuent a( model o, vi st a) ;
vi st a. set Vi si bl e( true) ;
}
}
El controlador mantiene
referencias a la vista y el
modelo
Generalmente se encarga de
registrar la vista como
escuchador del modelo
El controlador provee las acciones que se han
de realizar en respuesta a los eventos del
usuario (obteniendo datos de la vista y
actualizando consecuentemente el modelo)
52
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Patrn MVC con delegacin de eventos y
objetos Action
El modelo de delegacin de eventos puede ser
utilizado por el programador para notificar eventos
propios (lo utilizara el modelo para notificar cambios
a la vista)
Java define un interfaz Action que permite
encapsular acciones en objetos. Posteriormente
estas acciones pueden ser asignadas a distintos
componentes grficos (las acciones seran la parte
controlador del interfaz grfico)
53
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Modelo

class Cuent a
{
private int sal do;

private Pr oper t yChangeSuppor t changeSuppor t = new PropertyChangeSupport( this) ;

public Cuenta( int sal do)
{ this. sal do = sal do; }

public int getSaldo( )
{ return sal do; }

public void ingresar( int cant i dad)
{
int sal doAnt i guo = sal do;
sal do = sal do + cant i dad;
changeSuppor t . firePropertyChange( "sal do" , sal doAnt i guo, sal do) ;
}

public void retirar( int cant i dad)
{
int sal doAnt i guo = sal do;
if ( cant i dad < sal do)
sal do = sal do - cant i dad;
else
sal do = 0;
changeSuppor t . firePropertyChange( "sal do" , sal doAnt i guo, sal do) ;
}

public void addPropertyChangeListener( Pr oper t yChangeLi st ener l i st ener )
{
changeSuppor t . addPropertyChangeListener( l i st ener ) ;
}
}
Notificamos a los observadores un cambio en la
propiedad saldo
Mtodo que permite registrar escuchadores
Creamos el objeto que gestionar la notificacin de
cambios pasando el propio objeto Cuenta como
parmetro
PropertyChangeSupport es una clase de utilidad
utilizada por objetos " beans" con propiendades
" bound (propiedades que notifican sus cambios).
54
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Controlador
class I ngr esar Act i on extends Abst r act Act i on
{
private Cuent a model o;
private GUI Cuent a vi st a;

public IngresarAction ( Cuent a model o, GUI Cuent a vi st a)
{ this. model o = model o;
this. vi st a = vi st a;
putValue( Act i on. NAME, "I ngr esar " ) ;
putValue( Act i on. SMALL_I CON, new ImageIcon( "C: \ \ i cons\ \ Dat aSt or e. gi f " ) ) ;
putValue( Act i on. SHORT_DESCRI PTI ON, "I ngr esamos una cant i dad en l a cuent a" ) ;
}

public void actionPerformed( Act i onEvent e)
{ int cant i dad = vi st a. getSaldo( ) ;
model o. ingresar( cant i dad) ;
}
}

class Ret i r ar Act i on extends Abst r act Act i on
{
private Cuent a model o;
private GUI Cuent a vi st a;

public RetirarAction ( Cuent a model o, GUI Cuent a vi st a)
{ this. model o = model o;
this. vi st a = vi st a;
putValue( Act i on. NAME, "Ret i r ar " ) ;
putValue( Act i on. SMALL_I CON, new ImageIcon( "C: \ \ i cons\ \ Dat aExt r act . gi f " ) ) ;
putValue( Act i on. SHORT_DESCRI PTI ON, "Ret i r amos una cant i dad en l a cuent a" ) ;
}

public void actionPerformed( Act i onEvent e)
{ int cant i dad = vi st a. getSaldo( ) ;
model o. retirar( cant i dad) ;
}
}
Cada clase Action tendr un mtodo
ActionPerformed que se llamar cuando un
componente grfico asociado desencadene una
accin
La clase Action puede definir algunos valores
determinados como el nombre de la accin, el icono,
la descripcin, etc. que compartirn todos los
componentes grficos que utilicen dicha accin
Se crea una clase que extiende a AbstractAction
para cada accin a realizar en el interfaz
Cada clase Action tiene acceso al modelo y a la vista
(en este ejemplo se le suministran como parmetros
en el constructor
55
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Vista
class GUI Cuent a extends J Fr ame implements Pr oper t yChangeLi st ener
{ private Cuent a mi Cuent a;
private J Label l abel Sal do = new JLabel( " Sal do : " ) ;
private J Label l abel Cant i dad = new JLabel( "0") ;
private J But t on bI ngr esar = new JButton( ) , bRet i r ar = new JButton( ) ;
private J Text Fi el d t = new JTextField( 20) ;
private J MenuBar j MenuBar = new JMenuBar( ) ;
private J Menu j MenuAcci ones = new JMenu( "Acci ones" ) ;
private J MenuI t emmI ngr esar = new JMenuItem( ) ;
private J MenuI t emmRet i r ar = new JMenuItem( ) ;
Cont ai ner cont ent Pane = getContentPane( ) ;

public GUICuenta( Cuent a c)
{ mi Cuent a=c;
mi Cuent a. addPropertyChangeListener( this) ;
init( ) ;
setBounds( 0, 0, 232, 134) ;
}

public void update( )
{ l abel Cant i dad. setText( I nt eger . toString( mi Cuent a. getSaldo( ) ) ) ; }

public void init( )
{ setTitle( "Cuent a MVC 3" ) ;
setDefaultCloseOperation( EXI T_ON_CLOSE) ;

J Panel panel Bot ones = new JPanel( new GridLayout( 1, 2) ) ;
J Panel panel Sal do = new JPanel( ) ;
panel Bot ones. add( bI ngr esar ) ;
panel Bot ones. add( bRet i r ar ) ;
panel Sal do. add( l abel Sal do) ;
panel Sal do. add( l abel Cant i dad) ;
j MenuAcci ones. add( mI ngr esar ) ;
j MenuAcci ones. add( mRet i r ar ) ;
j MenuBar . add( j MenuAcci ones) ;
setJMenuBar( j MenuBar ) ;
cont ent Pane. add( panel Sal do, Bor der Layout . NORTH) ;
cont ent Pane. add( t , Bor der Layout . CENTER) ;
cont ent Pane. add( panel Bot ones, Bor der Layout . SOUTH) ;
}


La vista mantiene una referencia a la cuenta y llama
al mtodo addPropertyChangeListener de la misma
pasndose a si misma como parmetro

public void setIngresarAction( Act i on act i on)
{ bI ngr esar . setAction( act i on) ;
mI ngr esar . setAction( act i on) ;
}

public void setRetirarAction( Act i on act i on)
{ bRet i r ar . setAction( act i on) ;
mRet i r ar . setAction( act i on) ;
}

public int getSaldo( )
{ return I nt eger . parseInt( t . getText( ) ) ; }

public void propertyChange( Pr oper t yChangeEvent evt )
{
if ( evt . getPropertyName( ) . equals( "sal do" ) )
{
I nt eger sal do = ( I nt eger ) evt . getNewValue( ) ;
l abel Cant i dad. setText( I nt eger . toString( sal do. intValue( ) ) ) ;
}
}
}

La vista incluye mtodos
para asignar acciones a
sus componentes grficos
La vista incluye un mtodo
propertyChange que hace
la funcin del antiguo
update, se llama cuando se
produce un cambio en un
objeto registrado (la
cuenta)
Los componentes grficos se crean sin
especificarles que accin van a llevar a cabo
56
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Ejemplo

public class Cuent aMVC3
{
public static void main( St r i ng [ ] ar gs)
{
Cuent a model o = new Cuenta( 0) ;
GUI Cuent a vi st a = new GUICuenta( model o) ;
vi st a. setIngresarAction( new IngresarAction( model o, vi st a) ) ;
vi st a. setRetirarAction( new RetirarAction( model o, vi st a) ) ;
vi st a. setVisible( true) ;
}
}
Una clase externa se encarga de crear el modelo, la
vista y los controladores (adems de relacionar
dichos controladores con la vista y el modelo)
Los componentes grficos obtienen el nombre,
icono y descripcin de su accin correspondiente
57
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua
Diseo aplicaciones grficas
Patrn Modelo-Vista-Controlador
Ventajas
Es fcil utilizar distintas combinaciones de vistas o controladores para
el mismo modelo
Los cambios son ms fciles de realizar al estar las distintas partes
desligadas unas de otras
Las pruebas son ms fciles de realizar porque pueden realizarse a
cada una de las partes por separado
Inconvenientes
Aumento de la complejidad del software desarrollado
El mecanismo de notificacin del modelo puede representar un
problema de eficiencia si los cambios son frecuentes
La vista y el controlador pueden verse fcilmente afectados por
cambios en el modelo
La vista y el controlador suelen estar fuertemente relacionados y su
separacin estricta es complicada
Mas informacin en:
http://java.sun.com/developer/technicalArticles/javase/mvc/

También podría gustarte