Академический Документы
Профессиональный Документы
Культура Документы
1ra. Parte:
Introducción
La biblioteca AWT:
java.awt, java.awt.event Componentes predefinidas
Componentes Label
Componentes predefinidas
Agregación de componentes TextField
Las interfaces se dibujan a sí mismas: funciones de
dibujo Button
Creación de nuevas componentes
Interacción con el usuario: gestión de eventos TextArea
Emisión de eventos
Recepción y procesamiento de eventos Frame
Layout de componentes
1
Aspectos interactivos Ejemplo: código (III)
...
Editar texto public void actionPerformed (ActionEvent e) {
Cerrar String command = e.getActionCommand ();
del campo
ventana if (command.equals ("Quit")) dispose ();
else if (command.equals ("Load")) load ();
else if (command.equals ("Save")) save ();
}
Leer el fichero indicado public void windowClosing (WindowEvent e) { dispose (); }
en el campo de texto, public void windowActivated (WindowEvent e) {}
public void windowClosed (WindowEvent e) {}
asignar como string public void windowDeactivated (WindowEvent e) {}
del área de texto public void windowDeiconified (WindowEvent e) {}
public void windowIconified (WindowEvent e) {}
Escribir string del área de texto en el public void windowOpened (WindowEvent e) {}
...
fichero indicado en el campo de texto
Editar texto multilínea
this.addWindowListener (this);
load.addActionListener (this);
save.addActionListener (this);
quit.addActionListener (this);
} // Fin del constructor
2
Jerarquía de componentes AWT:
Resumen el package java.awt
Jerarquía = Herencia
Programar un IU para una aplicación en Java
involucra:
Composición
Layout
Eventos
Paint
2da. Parte:
Componentes
3
Clases en el ejemplo Código del ejemplo
Frame Converter /**
* Does the conversion from metric to U.S., or vice versa, and
* updates the appropriate ConversionPanel.
*/
Label
Choice void convert(ConversionPanel from) {
TextField ConversionPanel to;
if (from == metricPanel)
funcionalidad
ScrollBar to = usaPanel;
ConversionPanel else
to = metricPanel;
4
Código del ejemplo Código del ejemplo
class ConversionPanel extends Panel //Add the pop-up list (Choice). + componentes
implements ActionListener,
AdjustmentListener, unitChooser = new Choice();
ItemListener { for (int i = 0; i < units.length; i++) { //Populate it.
TextField textField; unitChooser.add(units[i].description);
Choice unitChooser; }
Scrollbar slider; c.weightx = 0.0; //The default value.
int max = 10000; c.gridwidth = GridBagConstraints.REMAINDER; //End a row.
int block = 100; Panel interno gridbag.setConstraints(unitChooser, c);
Converter controller; add(unitChooser);
Unit[] units; unitChooser.addItemListener(this);
5
Jerarquía de componentes:
Código del ejemplo la clase java.awt.Container
/** Respond to the text field */ Jerarquía = Composición
public void actionPerformed(ActionEvent e) { Las interfaces se construyen agregando componentes a
setSliderValue((double)Double.valueOf(
textField.getText()).doubleValue());
modo de piezas
Respuesta
controller.convert(this); La jerarquía de componentes debe empezar con una ventana
a eventos
} (frame) o un applet
/** Respond to the choice */ Una componente sólo puede añadirse a un Container
public void itemStateChanged(ItemEvent e) { Agregar: add(Component)
controller.convert(this); Retirar: remove(Component)
}
Las ventanas no pueden añadirse a otra componente
/** Respond to the slider. */ La colocación de las componentes en un contenedor se
public void adjustmentValueChanged(AdjustmentEvent e) { puede definir:
textField.setText(String.valueOf(e.getValue()));
Mediante layout managers de distintos tipos
controller.convert(this);
} A mano, con posiciones absolutas
POO - EPS - UAM 31 POO - EPS - UAM 34
6
Apariencia de las componentes: Refresco de las componentes
paint(Graphics) de Component
Refresco = (re)dibujar
La apariencia en pantalla de cada subclase de Component
está definida por el código de paint(Graphics) Cuándo
El código de paint consiste en llamadas a funciones de Al desplegar una ventana o cambiarle el tamaño
dibujo sobre el objeto de tipo Graphics Al hacer visible un componente
Es poco factible cambiar el dibujo de las componentes Al cambiar desde el programa propiedades visuales de un
predefinidas componente
(En cambio, es fácil cambiar su respuesta a eventos)
Normalmente no se redefine paint de las clases predefinidas Al ser necesario cambiar la apariencia de uno
Para modificar su apariencia, modificar su estado (el sistema refleja componente para reflejar cambios en la aplicación
los cambios en la pantalla automáticamente)
En componentes personalizadas desde cero sí se define paint
Quién solicita
Es importante que paint no sea costoso de ejecutar En los tres primeros casos, el sistema AWT.
Utilizar hilos si es necesario para no bloquear el repintado En el último caso, el mismo programa
POO - EPS - UAM 37 POO - EPS - UAM 40
El dibujo comienza por el componente más alto en El proceso de dibujo en sí sólo puede llevarse
la jerarquía que necesita ser dibujado a cabo cuando lo diga el sistema AWT
Por ejemplo, un Frame. Estos procesos se deben ejecutar sin
Se baja por la jerarquía, dibujando cada interrupción.
componente intermedio, hasta las hojas. AWT hace que todos los dibujos ocurran en el
El sistema de dibujo de AWT organiza este mismo hilo.
procedimiento El dibujo no puede insumir mucho tiempo
No se pueden hacer suposiciones sobre el orden Si es necesario, crear un hilo separado para
relativo de dibujo de las componentes ejecutar alguna operación larga
7
Refresco de las componentes: el
Gestión de eventos
objeto Graphics
Los eventos son objetos de distintas subclases de AWTEvent
Es el argumento de los métodos update y paint
Se generan eventos cuando:
Normalmente nos llega a nuestro código desde AWT
Se produce input del usuario: MouseEvent,KeyEvent
Provee métodos para: Un widget se acciona: ActionEvent, TextEvent,
Dibujar y rellenar rectángulos, arcos, líneas, óvalos, AdjustmentEvent
polígonos, textos e imágenes. Una ventana es manipulada: WindowEvent
Otras causas: ContainerEvent, ComponentEvent,
Obtener o cambiar el color, tipo de fuente o área de PaintEvent, etc.
clipping actuales.
Los manejadores de eventos (listeners) pueden ser instancias de
Cambiar el modo de dibujo. cualquier clase.
Sólo es necesario que la clase implemente la interfaz listener
correspondiente
8
java.awt.Graphics
Abstract Window Toolkit (AWT) Argumento de paint() y update()
Dibujo de primitivas gráficas:
drawLine(int,int, int,int),
drawRect(int,int,int,int),
Repaso de clases básicas drawArc(int,int,int,int,int,int),
fillRect(int,int,int,int)
drawString(String,int,int)
drawImage(Image,int,int[,int,int],ImageObserver)
Estado:
Componente sobre la que dibujar: getGraphics() de Component
Origen de coordenadas: translate(int,int)
Área de clip: getClip(), setClip(int,int,int,int)
Color: setColor(Color), getColor()
Font: setFont(Font), getFont()
Modo XOR: setXORMode(Color)
POO - EPS - UAM 52
9
Modelo de eventos: ejemplo
Abstract Window Toolkit (AWT)
public class Beeper implements ActionListener {
...
3ra. Parte: //where initialization occurs:
button = new Button("Click Me");
Gestión de Eventos button.addActionListener(this);
...
public void actionPerformed(ActionEvent e){
...//Implements the answer...
}
}
10
Utilización de adapters Adaptadores: código
class MyListener extends MouseAdapter {
Este tipo de código resulta más difícil de leer y
public void mouseEntered (MouseEvent e) {
mantener.
... // Respuesta de la ventana al evento
Para evitar la implementación vacía de métodos, }
AWT provee clases adapters }
implementan listeners con métodos vacíos; class Ventana extends Frame {
proporciona los adaptadores en java.awt.event; Ventana () {
para cada interfaz de listener con más de un método. Button boton = new Button ();
Crear una subclase del adaptador definiendo sólo boton.addMouseListener (new MyListener ());
los métodos que interesen ...
}
}
POO - EPS - UAM 61 POO - EPS - UAM 64
11
Adaptador como clase anónima
Abstract Window Toolkit (AWT)
class Ventana extends Frame {
private String nombre;
Ventana () {
Button boton = new Button ();
boton.addMouseListener (
4ta. Parte:
new MouseAdapter () { Gestión de Eventos:
public void mouseEntered (MouseEvent e) {
... Implementación de los listeners
System.out.println (nombre);
...
}
}
);
}
}
12
Contenido de las clases de eventos Ejemplo de ActionListener
13
Clases de Layout Managers
Abstract Window Toolkit (AWT)
Existen distintas clases de manager para
5ta. Parte: distintos tipos de layout
Layout de componentes dentro de un Predefinidos por AWT
contenedor Simples: FlowLayout y GridLayout
Específicos: BorderLayout, CardLayout
Ultra flexible:GridBagLayout
Cada uno tiene sus propias “reglas” de uso
Objeto que controla el tamaño y posición de los A menos que el programador lo cambie, cada
componentes de un contenedor. contenedor tiene su propia instancia de
Implementan la interfaz LayoutManager LayoutManager asociada.
¿Por qué layout managers? Es consultado cada vez que que el
La posición de una componente depende de las componentes contenedor tiene que cambiar su apariencia.
que la rodean y del espacio disponible para el grupo
La mayoría de los LayoutManagers no
Un layout manager por encima de las componentes requiere que se llame explícitamente a sus
individuales impone un orden
métodos
Las componentes negocian su colocación y tamaño con el
layout manager.
POO - EPS - UAM 81 POO - EPS - UAM 84
14
Cómo elegir LayoutManager Ver apéndice C
Escenario:
Se necesita mostrar una componente en tanto espacio Clases de layout managers
como sea posible.
Considere BorderLayout o GridBagLayout
Con BorderLayout, se debe poner la componente
ávida de espacio en el centro.
Con GridBagLayout es necesario que la propiedad
fill de las restricciones sea
fill=GridBagConstraints.BOTH.
Si no importa que las otras componentes sean igual de
grandes, se puede usar un GridLayout.
int getKeyCode()
add(), remove(), removeAll(): en void setKeyCode(int)
cualquier momento. Obtiene o cambia el código de tecla asociado al evento.
layout(): usualmente como resultado de una La clase KeyEvent define varias constantes de códigos para las
teclas comunes. Por ejemplo:
solicitud paint, y no directamente. VK_A especifica la tecla con rótulo A
VK_ESCAPE especifica la tecla ESCAPE.
preferredSize(), minimumSize(): el
void setModifiers(int)
retorno es sólo una sugerencia, el programa tiene Cambia el estado de las teclas modificadoras para el evento.
que mantener estos valores.
POO - EPS - UAM 87 POO - EPS - UAM 90
15
BorderLayout (III)
Abstract Window Toolkit (AWT)
La parte central es la que más varía con la ventana.
Las otras partes sólo varían para mantener ocupado
Apéndice C todo el espacio disponible.
Clases de layout managers Manager por omisión de las ventanas.
Por omisión, no tiene ninguna distancia al borde
Se puede especificar con este constructor:
BorderLayout FlowLayout
16
FlowLayout (III) GridLayout
17
CardLayout CardLayout (IV)
Eligiendo componente:
public void first(Container parent)
public void next(Container parent)
public void previous(Container parent)
public void last(Container parent)
public void show(Container parent,
String name)
El primer argumento siempre es el contenedor para
quien el manager está trabajando.
18
GridBagLayout (III) Restricciones de GridBagLayout
(II)
19
Restricciones de GridBagLayout GridBagLayout: Ejemplo
(V)
weightx, weighty
Especificar los pesos es un arte que puede tener un Cada componente tan
impacto significativo en la apariencia final. grande como sea posible
Son usados para determinar cómo se distribuye el GridBagLayout gridbag = new GridBagLayout();
espacio entre las columnas (filas); esto es importante
GridBagConstraints c = new GridBagConstraints();
para el comportamiento de redimensionamiento.
setLayout(gridbag);
A menos que se especifique un valor distinto de cero, c.fill = GridBagConstraints.BOTH;
todas las componentes se agrupan juntas en el centro del
c.weightx = 1.0;
contenedor. Esto es porque cuando el peso es 0.0
(default), el GridBagLayout pone cualquier espacio makebutton("Button1", gridbag, c);
extra en los márgenes externos del contenedor. makebutton("Button2", gridbag, c);
(continúa) makebutton("Button3", gridbag, c);
20
GridBagLayout: Ejemplo GridBagLayout: Ejemplo
Si no estuviera (es
decir, weightx = 0)
c.gridwidth = 1; //reset to the default
GridBagLayout gridbag = new GridBagLayout(); c.gridheight = 2; ocupa dos filas
GridBagConstraints c = new GridBagConstraints(); c.weighty = 1.0;
setLayout(gridbag);
makebutton("Button8", gridbag, c);
c.fill = GridBagConstraints.BOTH;
c.weighty = 0.0; //reset to the default
c.weightx = 1.0;
makebutton("Button1", gridbag, c); c.gridwidth = GridBagConstraints.REMAINDER; //end of row
c.weightx = 0.0; //reset to the default c.weighty = 1.0; es el único con valor > 0
makebutton("Button5", gridbag, c); //another row makebutton("Button8", gridbag, c);
c.weighty = 0.0; //reset to the default
c.gridwidth = GridBagConstraints.RELATIVE; //next to last
c.gridwidth = GridBagConstraints.REMAINDER; //end of row
makebutton("Button6", gridbag, c);
c.gridheight = 1; //reset to the default
c.gridwidth = GridBagConstraints.REMAINDER; //end of row makebutton("Button9", gridbag, c);
makebutton("Button7", gridbag, c); makebutton("Button10", gridbag, c);
POO - EPS - UAM 122 POO - EPS - UAM 125
21
Trabajando sin Layout Manager java.awt.Button
Estado y propiedades
Se debe utilizar un layout manager siempre que sea posible. Constructores: Button(), Button(String)
Con ellos es más fácil redimensionar los contenedores y El string se utiliza como etiqueta del botón
Cambiar / acceder a la etiqueta: GetLabel(),
ajustar la apariencia de componentes dependientes de la SetLabel(String)
plataforma. También es fácil reutilizarlos. Botón activo / inactivo: setEnabled(boolean)
Operación
Si el contenedor no será reutilizado, no puede ser Emite un ActionEvent al ser pulsado
redimensionado, y controla por completo los factores que Identificación para el evento de acción:
setActionCommand(String)
normalmente dependen de la plataforma (fuentes y aspecto Asocia un string al botón (por omisión, el mismo que la etiqueta)
El string formará parte de la información incluida en los
de los componentes), entonces puede tener sentido un layout ActionEvent's emitidos por el botón (ver getActionCommand()
absoluto. de ActionEvent)
...
public void actionPerformed (ActionEvent e) {
String command = e.getActionCommand();
if (command.equals ("Disable")) {
Abstract Window Toolkit (AWT) b1.setEnabled (false);
b2.setEnabled (false);
b3.setEnabled (true);
}
else {
Apéndice D b1.setEnabled (true);
b2.setEnabled (true);
Widgets AWT b3.setEnabled (false);
}
Clases predefinidas de componentes }
}
estándar
22
class CheckboxDemo extends Frame {
Widgets de selección CheckboxDemo () {
setLayout (new GridLayout (1, 2));
Panel p1 = new Panel ();
Checkbox List Choice Menu Checkbox cb = new Checkbox ();
cb.setLabel ("Checkbox 1");
cb.setState (true);
p1.add (cb);
p1.add (new Checkbox ("Checkbox 2"));
ItemEvent lleva p1.add (new Checkbox ("Checkbox 3"));
número de item Emiten add (p1);
ActionEvents
Panel p2 = new Panel ();
Doble click CheckboxGroup group = new CheckboxGroup ();
p2.add (new Checkbox ("Checkbox 4", group, false));
Selección múltiple Ahorro de espacio p2.add (new Checkbox ("Checkbox 5", group, false));
p2.add (new Checkbox ("Checkbox 6", group, false));
add (p2);
}
Emiten ItemEvents }
POO - EPS - UAM 133 POO - EPS - UAM 136
java.awt.Checkbox
Descripción
Botón seleccionable con dos estados: seleccionado /
deseleccionado
Agrupable en grupos de botones de selección excluyente
(radio buttons)
Estado y propiedades
Checkbox(), Checkbox(String),
Checkbox(String,boolean)
getLabel(), setLabel(String)
getState(), setState(boolean)
Operación
Emite un ItemEvent al cambiar de estado Descripción
El item asociado el evento es el label del checkbox
Lista de selección desplegable
Identificación del item desde el evento: Uno de los elementos de la lista está seleccionado
getItem()→String (label del checkbox) Estado y propiedades
getItemSelectable()→Object (la componente checkbox) add(String), getItem(int), getItemCount()
Botones excluyentes: grupos de Checkbox'es select(int), select(String),
Crear objeto de la clase CheckboxGroup isIndexSelected(int), getSelectedItem() →
Utilizar el constructor
String, getSelectedIndex() → int
Checkbox(String,boolean,CheckboxGroup) Operación
Los checkbox creados con el mismo grupo como argumento forman
un grupo
Emite un ItemEvent al cambiar la selección
Sólo un checkbox de un grupo puede estar seleccionado El item asociado el evento es el string del item seleccionado
23
java.awt.List
...
Panel p = new Panel ();
Descripción p.setLayout (new GridLayout (2, 1, 10, 10));
Lista de selección con barras de scroll p.add (spanish);
El modo de selección puede ser simple o múltiple p.add (italian);
Estado y propiedades output = new TextArea (10, 40);
List(), List(int), List(int,boolean) output.setEditable (false);
add(String), add(String,int), remove(String),
remove(int), getItem(int), getItems(), add (output);
getItemCount(), getRows() add (p);
select(int), select(String), } // Fin del constructor
isIndexSelected(int), getSelectedItem() → ...
String, getSelectedIndex() → int,
getSelectedObjects() → Object[]
isMultipleMode(), setMultipleMode(boolean)
...
java.awt.List (cont.) public void actionPerformed (ActionEvent e) {
List list = (List) (e.getSource ());
String language = (list == spanish)? "Spanish" : "Italian";
output.append ("Action event on " + list.getSelectedItem ()
+ " in " + language + ".\n");
Operación }
public void itemStateChanged (ItemEvent e) {
Seleccionar / deseleccionar item: emite List list = (List) (e.getItemSelectable ());
ItemEvent String language = (list == spanish)? "Spanish" : "Italian";
int index = ((Integer) (e.getItem ())) .intValue ();
El item asociado al evento es el número de if (e.getStateChange () == ItemEvent.SELECTED) {
output.append ("Select event on item " + index
posición del item seleccionado + " (" + list.getItem (index) + ")"
+ " in " + language + ".\n");
Doble click: emite ActionEvent con el texto del }
item seleccionado como action command string else output.append ("Deselect event on item " + index
+ " (" + list.getItem (index) + ")"
+ " in " + language + ".\n");
}
}
24
java.awt.Menu java.awt.Menu (cont.)
Operación
Descripción
MenuItem emite sólo ActionEvent como un botón, con
Conjunto de items de distintas modalidades:
el label del item pulsado como action command string
MenuItem: tipo botón
Source del evento: el item o el Menu contenedor del item
CheckboxMenuItem: tipo checkbox
CheckboxMenuItem emite sólo ItemEvent como un
Menu: submenú checkbox, con el label del item seleccionado /
MenuItem
deseleccionado como label del evento
Source del evento: el propio CheckboxMenuItem
Menu CheckBoxMenuItem
25
class TextDemo extends Frame implements ActionListener {
java.awt.TextComponent TextField textField;
TextArea textArea;
TextDemo () {
setLayout (new FlowLayout ());
Descripción textField = new TextField (20);
Superclase de TextField y TextArea textArea = new TextArea (5, 20);
Texto editable, seleccionable textArea.setEditable (false);
java.awt.TextField
Descripción
Texto editable de una sola línea
Estado y propiedades (además de las de TextComponent)
TextField(), TextField(String),
TextField(String,int)
getColumns(), setColumns(int)
getEchoChar(), setEchoChar(char), echoCharIsSet()
Operación
Emite un TextEvent cuando se cambia un carácter del texto
Puede interesar procesar KeyEvent's si interesa obtener el
carácter
Cuando se pulsa 'Enter' emite un ActionEvent con el texto del
widget como action command string
java.awt.TextArea java.awt.Dialog
Descripción Descripción
Texto editable multilínea con scrolling Depende de otra ventana:
Estado y propiedades (además de las de TextComponent) Se destruye cuando se destruye la ventana principal
TextArea(), TextArea(String), Desaparece cuando se minimiza la ventana principal
TextArea(String,int,int) Estado y propiedades
Scrollbars: TextArea(String,int,int,int), Dialog (Frame [,String] [,boolean])
TextArea.SCROLLBARS_NONE,
SCROLLBARS_VERTICAL_ONLY...
Modal / no modal: isModal(), setModal(boolean)
getColumns(), setColumns(int), getRows(), setRows(int)
isResizeable(), setResizeable(boolean)
append(String), insert(String,int), replaceRange(String,int,int)
de Window
Operación FileDialog extends Dialog
Emite un TextEvent cuando se cambia un carácter del texto getDirectory(), setDirectory(String)
No emite ActionEvent's getFile(), setFile(String)
26
class DialogWindow extends Frame implements ActionListener {
private SimpleDialog dialog;
private TextArea textArea;
java.awt.Dialog
public DialogWindow () {
textArea = new TextArea (5, 40);
textArea.setEditable (false);
add ("Center", textArea);
Button button = new Button ("Click to bring up dialog");
button.addActionListener (this);
Panel panel = new Panel ();
panel.add (button);
add ("South", panel);
}
public void actionPerformed (ActionEvent event) {
if (dialog == null)
dialog = new SimpleDialog (this, "A Simple Dialog");
dialog.setVisible (true);
}
public void addLine (String text) {
textArea.append(text + "\n");
}
}
Widgets personalizados
class SimpleDialog extends Dialog implements ActionListener {
TextField field;
DialogWindow parent; class Boton extends Canvas implements MouseListener {
Button setButton; private boolean selected = false;
SimpleDialog (Frame w, String title) { protected String label;
super (w, title, false); public Boton (String str) {
parent = (DialogWindow) w; label = str;
Panel p1 = new Panel (); addMouseListener (this);
p1.setLayout (new GridLayout (2, 1)); new Mover (this);
Label label = new Label ("Enter text here:"); }
p1.add (label); public void paint (Graphics g) {
field = new TextField (40); Dimension dim = getSize ();
aspecto visual
...
Panel p2 = new Panel(); Métodos para negociar
p2.setLayout (new FlowLayout (FlowLayout.RIGHT)); tamaño con layout managers
Button b = new Button ("Cancel");
b.addActionListener (this); ...
setButton = new Button ("Set"); public Dimension getPreferredSize () {
setButton.addActionListener (this); FontMetrics metrics = getGraphics () .getFontMetrics ();
p2.add (b); return new Dimension (metrics.stringWidth (label) + 20,
p2.add (setButton); metrics.getHeight () + 10);
}
add ("South", p2);
pack ();
public Dimension getMinimumSize () {
} Dimension dim = getPreferredSize ();
return new Dimension (dim.width / 2, dim.height / 2);
public void actionPerformed (ActionEvent event) { }
Object source = event.getSource();
if ((source == setButton) || (source == field)) public Dimension getMaximumSize () {
parent.addLine (field.getText()); Dimension dim = getPreferredSize ();
field.selectAll (); return new Dimension (dim.width * 2, dim.height * 2);
setVisible (false); }
...
}
}
POO - EPS - UAM 159 POO - EPS - UAM 162
27
...
public void mouseClicked (MouseEvent e) {
1. Inicio 4. Exit
selected = !selected;
Respuesta visual (feedback)
if (selected) {
a acción del usuario
setBackground (Color.black);
setForeground (Color.white);
}
else {
setBackground (Color.white);
2. Enter 5. Enter
setForeground (Color.black);
}
}
...
public String getLabel () { return label; } class BotonAccion extends Boton {
public void setLabel (String str) { private ActionListener multicaster = null;
label = str; public BotonAccion (String str) { super (str); }
Interfaz para controlar el estado del widget
pointedAt = true;
Más feedback a
repaint ();
}
public void mouseExited (MouseEvent e) {
pointedAt = false;
repaint ();
}
}
28