Presentacion Swing(1)

Post on 12-Aug-2015

38 views 1 download

Transcript of Presentacion Swing(1)

CREANDO GUIs CON JFC/SWING

Programación en Java

Adolfo Rodríguez de Soto Carlos Testera González Conrado Andreu Capdevila

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN I

JFC Java Foundation Classes. JFC abarca varias características para dotar

de funcionalidad gráfica a Java. Componentes GUI Swing. Soporte de aspecto (look-and-feel). API de accesibilidad. API 2D. Soporte de arrastrar y soltar. Internacionalización.

JFC

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN II

De la JFC, veremos los componentes Swing y los aspectos relacionados (no exclusivos de Swing) para poder manejarlos, como: Eventos. Acciones. Clases internas y anónimas. Interfaces y clases adaptadoras. Administradores de diseño.

Lo que necesitamos

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN III

ANTECEDENTES Java 1.0 utilizaba AWT (Abstract Window

Toolkit). AWT delega la creación de elementos de

interfaz de usuario a las herramientas nativas de la GUI de la plataforma de destino (Windows, Solaris, Macintosh, etc).

En teoría solo sería necesario especificar localización y comportamiento de los componentes y se podrían ejecutar en cualquier plataforma con el aspecto de esa plataforma.

Antecedentes

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN IV

PROBLEMAS DEL AWT El mismo elemento de interfaz de usuario tiene

sutiles diferencias de comportamiento según la plataforma.

Ciertos entornos gráficos no tienen una colección de componentes gráficos tan rica como por ejemplo Windows o Macintosh. Esto reduce la biblioteca portable al “máximo común

denominador” que suele ser muy pequeño. El resultado fueron interfaces gráficas poco

atractivas, con menor funcionalidad de la requerida y con fallos al cambiar de plataforma.

Problemas de AWT

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN V

Swing no reemplaza a AWT. Ofrece al usuario componentes de interfaz más capaces y completos.

AWT abarca muchas funcionalidades necesarias: Eventos. Aspectos. Administradores de diseño.

Los elementos de interfaz AWT siguen existiendo, pero no se me ocurre ninguna situación donde sean necesarios.

Swing - AWT

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN VI

Los componentes Swing se dibujan sobre ventanas en blanco, de forma que los elementos tienen el mismo aspecto y comportamiento en todas las plataformas.

Swing aporta numerosas ventajas … Conjunto de elementos de interfaz mucho más extenso y

útil que AWT. No depende de la plataforma para mostrar los elementos

(se reducen mucho los errores por migración). El manejo de los elementos no varía con la plataforma.

… y algún inconveniente: Algo más lento que AWT. El uso de la aplicación no se adapta a la plataforma

(resuelto con los aspectos (look-and-feel)).

Swing – ventajas e inconvenientes

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

INTRODUCCIÓN VII

Otros aspectos interesantes: Las clases Swing se encuentran en el paquete javax.swing No es recomendable mezclar elementos Swing con

elementos AWT. Usaremos por defecto el aspecto Metal, un aspecto creado

por Sun independiente de la plataforma. Ya existen entornos visuales muy potentes y elaborados

para el diseño de interfaces gráficas (NetBeans, VisualAge, Jdeveloper …). Tener cuidado con el código generado por cada uno de ellos y por la biblioteca requerida.

– Obligatorio: leer

http://docs.oracle.com/javase/tutorial/uiswing/

– excepto NetBeans, concurrencia, otros rasgos de Swing, drag and drop, sonido, applets, javaFX, modo full-screen

Cosas sueltas

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Hola Mundo en Swing

}

Import javax.swing.*;

public class HolaMundoSwing {

private static void crearYMostrarGUI() {

//Crear la ventana principal JFrame frame = new JFrame("HolaMundoSwing");

frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);

//Añadir la etiqueta JLabel label = new JLabel("Hola Mundo"); frame.getContentPane().add(label);

//Visualizar la ventana frame.setVisible(true); }

public static void main(String[] args) {

//Planificar la aplicación para ejecutar el hilo de evento javax.swing.SwingUtilities.invokeLater( new Runnable() { public void run() { crearYMostrarGUI(); } });

} }

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MARCOS I

Toda componente para ser visualizada debe ser parte de una jerarquía de componentes.

Cada componente sólo puede estar contenida en una componente.

Un marco es una ventana del nivel más alto (no está contenida en otra). JDialog, JApplet.

La clase Swing para generar marcos es JFrame. Es una de las pocas clases Swing que no se dibujan en un

lienzo, sino que las dibuja el sistema de ventanas de la plataforma destino.

Los marcos son ejemplos de contenedores (contiene otros elementos de la interfaz de usuario).

Algunos aspectos útiles: Inicialmente su tamaño es de 0 x 0 píxeles (hay que darle

tamaño). Su posición inicial es la coordenada (0,0), la esquina superior

izquierda de la pantalla (hay que posicionarlo). Inicialmente es invisible (hay que hacerlo visible).

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MARCOS II

Veamos el código que genera el marco de la figura.

Como crear un marco

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

La estructura de un JFrame es muy compleja. Una de sus partes es lo que se conoce como cuadro de contenido, un contenedor donde se añadirán los componentes (nunca se añaden directamente al frame).

Los métodos utilizados con los marcos (y con cualquier otra clase) no tienen por qué ser de dicha clase. Puede haberlos heredado de las clases de las que desciende. Aquí se muestra la jerarquía de clases de JFrame. Es solo un ejemplo. Para otros componentes podéis consultar la API.

MARCOS III

Cuadro de contenido

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MVC I

Todos los componentes Swing tienen tres características: Su contenido, como el estado de un botón (pulsado o

no), o el texto de un campo de texto. Su aspecto visual (color, tamaño, etc). Su comportamiento (la reacción a los eventos).

El aspecto visual puede variar sin que ello afecte al contenido, o dicho estado podrá modificarse según el comportamiento, pero tampoco modificará el contenido del componente.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MVC II

Para recoger dicho comportamiento, Swing utiliza un patrón de diseño de software denominado Patrón Modelo-Vista-Controlador (MVC – Model-View-Controller).

Este patrón implementa tres clases separadas: El modelo, que guarda el contenido. La vista, que muestra el contenido. El controlador, que manipula la entrada del usuario.

El patrón especifica como interactúan estos tres objetos.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MVC III

El modelo guarda el contenido y no tiene interfaz de usuario.

Por ej, para un campo de texto, el modelo es una cadena de caracteres que contiene el texto actual. Esto no es lo mismo que la vista del contenido; si el contenido es mayor que el campo, el usuario solo verá parte del texto.

El modelo debe implementar métodos para cambiar el contenido y devolver los contenidos. Por ej, un modelo de texto tiene métodos para añadir o quitar caracteres y devolver el texto como una cadena.

Modelo “El veloz zorro marrón salta sobre el perezoso perro.”

Vista

Modelo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MVC IV

El controlador manipula los eventos de las entradas del usuario, como los clicks de ratón y las pulsaciones de teclado. Decide entonces si traduce estos eventos en cambios en el modelo o en la vista.

En el ej, del campo de texto, si el usuario pulsa un carácter, el controlador llama al comando “insertar_caracter” del modelo (y el modelo le dice a la vista que se actualice).

Si el usuario pulsa una tecla de flecha, el controlador le dice a la vista que se desplace. Esto no tiene efecto en el texto, por lo que el modelo no sabrá nunca que este evento ha ocurrido.

Controlador

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

MVC V

Cuando utilicemos Swing generalmente no habrá que preocuparse del MVC.

Cada elemento tiene una clase envolvente (JButton, JTextField, etc) que guarda el modelo y la vista. Cuando se quiera saber cual es el contenido, la clase envolvente se lo pedirá al modelo.

En otras ocasiones si será necesaria su utilización, sobre todo trabajar directamente con el modelo (tablas), y casi nunca con la vista.

¿Es necesario usarlo?

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

LAYOUT MANAGERS I

Los componentes Swing necesitan organizarse de alguna manera dentro del contenedor en el que vayan a estar, ya sea un marco, un panel, etc.

Para permitir esto, Java utiliza lo que se conoce como administradores de diseño.

Existen varios administradores de diseño que organizan los componentes de forma diferente en un contenedor. Aunque la siguiente lista muestra unos cuantos, nosotros solo veremos y usaremos tres (los tres primeros). FlowLayout. BorderLayout. GridLayout. GridBagLayout. BoxLayout. CardLayout. SpringLayout.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

LAYOUT MANAGERS II

El uso básico de los layouts es bastante simple. La clase java.awt.Container de la cual derivan todos los contenedores (marcos, paneles, etc), tiene un método llamado setLayout que establece el layout manager para dicho contenedor.

El siguiente código muestra un JFrame al que le asignamos un BorderLayout y un panel al que le asignamos un GridLayout.

Luego solamente hay que añadir los componentes conforme al layout que estemos utilizando en el contenedor.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

LAYOUT MANAGERS III

El FlowLayout alinea los componentes horizontalmente hasta que no hay más espacio y entonces comienza una nueva fila.

Podemos hacer que los componentes estén centrados, alineados a la izquierda o a la derecha.

Podemos establecer los huecos horizontales y verticales entre los componentes (o solaparlos).

Los componentes aparecen en el orden en el que se añaden.

Para saber como hacer todo esto hay que consultar la API.

FlowLayout

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

LAYOUT MANAGERS IV

El BorderLayout organiza los componentes en cinco zonas.

Es el layout por defecto en los frames. No se suelen añadir componentes directamente

(ocupan toda la zona), sino paneles con otra organización interna.

El componente se añade especificando la zona (por tanto no importa el orden de agregación).

BorderLayout

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

LAYOUT MANAGERS V

El GridLayout es una disposición en cuadrícula. Al especificarlo en el contenedor se indican las filas y columnas que lo forman.

Al añadir los componentes se añaden en orden por filas y columnas.

También pueden especificarse huecos horizontales y verticales.

Todos los componentes de la rejilla tienen el mismo tamaño.

GridLayout

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS I

Un entorno GUI monitoriza eventos como las pulsaciones del teclado o los clics de ratón y la aplicación responde de una forma determinada a estos eventos. Programación Orientada a Eventos.

En el sistema de eventos de AWT se controla la forma en la que los eventos se transmiten desde los orígenes de eventos (botones o barras de desplazamiento) a los oyentes de eventos, que puede ser cualquier objeto.

Este modelo se conoce como modelo de delegación de eventos. Patrón Observador.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Patrón Observer

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS II

Los orígenes de eventos tienen métodos que permiten registrar oyentes de eventos. Cuando un evento ocurre en el origen, este envía una notificación del evento a todos los oyentes que se registraron para ese evento.

La información de un evento se encapsula en un objeto de tipo evento.

Todos los eventos derivan de la clase java.util.EventObject, aunque obviamente hay subclases para cada tipo de evento, tales como ActionEvent o WindowEvent.

Diferentes orígenes de eventos producen diferentes tipos de eventos. Por ej, un botón envía objetos ActionEvent, mientras que una ventana envía objetos WindowEvent.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Ejemplo Evento “Interesting”

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS III Un resumen de funcionamiento podría ser:

Un objeto oyente es una instancia de una clase que implementa una interfaz especial llamada interfaz oyente.

Un origen de eventos es un objeto que puede registrar objetos oyentes y enviarles objetos de eventos. La sintaxis para el registro suele tener la forma siguiente:

objetoOrigenEvento.add<Evento>Listener(objetoOyenteEvento); El origen de eventos envía objetos de eventos a todos los

oyentes registrados cuando ocurre ese evento. Los objetos oyente usarán la información del objeto evento para

determinar su reacción al evento.

Funcionamiento

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS IV Ejemplo de clic de un botón

utilizando una clase interna.

Clase principal

Clase para el frame

Clase para el panel que contiene el frame

Clase oyente INTERNA

Registro del oyente

Lo que ocurre al pulsar el botón

Clases internas

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS V Modificación del ejemplo anterior para utilizar clases

anónimas.

En el ej anterior aquí teníamos una instancia de una clase oyente interna.

Ahora no hemos definido ninguna clase. Usamos una CLASE INTERNA ANÓNIMA (una clase sin nombre). En este caso es una clase que implementa el interfaz ActionListener y por lo tanto hay que escribir el método actionPerformed.

Obviamente, estas clases solo pueden utilizarse cuando se necesita un único objeto de dicha clase.

Cases internas anónimas

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS VI Captura de los eventos de ventana.

Un objeto JFrame es el origen de un WindowEvent. Para capturar este evento hay que tener un oyente apropiado y registrarlo como oyente de la ventana.

Dicho oyente ha de ser una clase que implemente el interfaz WindowListener.

En ese interfaz hay siete métodos para dotar de funcionalidad a los siete eventos que pueden ocurrir.

Si queremos capturar el eventode cerrar ventana, dotaremos de funcionalidad a este y dejaremos al resto vacíos (recordar que hay que poner todos los métodos del interfaz).

La verdad es que esto no es muy elegante.

Eventos de ventana

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS VII Para arreglar el desastre del ejemplo anterior se utilizan lo

que se conocen como clases adaptadoras. Cada interfaz del oyente del AWT que tiene más de un

método viene con una clase compañera adaptadora que implementa todos los métodos de la interfaz pero que no hace nada con ellos.

Para los eventos de ventana, tenemos la clase WindowAdapter, que tiene siete métodos que no hacen nada.

Ojo, ahora ya no se implementa un interfaz, se hereda de una clase.

Por supuesto que con las clases adaptadoras pueden seguir usándose clases anónimas.

Clases adaptadoras

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS VIII AWT distingue dos tipos de eventos:

Semánticos: expresan lo que el usuario está haciendo (pulsar un botón, cambiar el texto).

De bajo nivel: hacen posibles los eventos semánticos. En el caso de pulsar el botón sería el hecho de pulsar el ratón, controlar sus movimientos, su liberación (pero solo si está dentro del área del botón, etc).

Hay cuatro clases de eventos semánticos: ActionEvent: para un clic de ratón, una selección de menú, seleccionar un

elemento de una lista o pulsar intro en un campo de texto. AdjustmentEvent: ajustar una barra de desplazamiento. ItemEvent: selección desde un conjunto de casillas de verificación o elementos

de una lista. TextEvent: cambiar el contenido de un campo o área de texto.

Hay siete clases de eventos de bajo nivel: ComponentEvent: cambiar el tamaño o posición de un componente (es la clase

base de todos los eventos de bajo nivel). KeyEvent: se ha pulsado o liberado una tecla. MouseEvent: el botón del ratón se ha pulsado, se ha soltado, se ha movido el

ratón o se ha arrastrado. MouseWheelEvent: ha girado la rueda del ratón. FocusEvent: un componente obtiene o pierde el foco. WindowEvent: el estado de la ventana a cambiado. ContainerEvent: se ha añadido o eliminado un componente.

Eventos semánticos y de bajo nivel

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS IX En un evento de teclado, cuando un usuario pulsa una tecla se

genera un evento keyPressed KeyEvent. Cuando se suelta se genera un keyRelease KeyEvent. El método keyTyped agrupa los dos anteriores e informa sobre el carácter que se ha generado.

Estos tres métodos se encuentran en el interfaz KeyListener. Java distingue entre caracteres y códigos virtuales de tecla, que se

corresponden con las teclas del teclado. Empiezan con el prefijo VK_, como VK_A o VK_SHIFT. Por ej, VK_A indica la tecla A (tanto mayúscula como minúscula, solo hay una tecla para ambas. En el método keyTyped y con getChar se puede obtener el carácter). Consultar la clase KeyEvent en la API para ver los códigos.

Para controlar el estado de las teclas Mayús, Ctrl, Alt y Meta se pueden controlar VK_SHIFT, VK_CONTROL, VK_ALT y VK_META, pero es más cómodo usar los métodos isShiftDown, isControlDown, isAltDown e isMetaDown.

Eventos de teclado

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS X Cuando el usuario hace clic con un botón del ratón llama a tres

métodos oyentes: mousePressed (al pulsar), mouseReleased (al soltar) y mouseClicked (engloba los dos, solo clics completos). A todos se les llama con un evento de tipo MouseEvent.

Se utiliza getClickCount para contar el número de clics y diferenciar entre un clic, doble clic, etc.

Si se mueve el ratón mientras se pulsa un botón, se llama al método mouseDragged.

Para escuchar los eventos del ratón se usan los interfaces MouseListener y MouseMotionListener (para los eventos que implican movimiento).

Hay más métodos, como mouseEntered, mouseExited y mouseMoved. Consultar la API y la tabla siguiente para más información.

Eventos del ratón

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS XI

Tabla resumen

INTERFAZ CLASE ADAPTADORA

MÉTODOS PARÁMETROS / ACCESORIOS

EVENTOS GENERADOS POR

ActionListener actionPerformed ActionEventgetActionCommandgetModifiers

AbstractButtonJComboBoxJTextFieldTimer

AdjustmentListener AdjustmentValueChanged AdjustmentEventgetAdjustablegetAdjustableTypegetValue

JScrollBar

ItemListener itemStateChanged ItemEventgetItemgetItemSelectablegetStateChange

AbstractButtonJComboBox

TextListener textValueChanged TextEvent

INTERFAZ CLASE ADAPTADORA

MÉTODOS PARÁMETROS / ACCESORIOS

EVENTOS GENERADOS POR

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS XIIINTERFAZ CLASE

ADAPTADORAMÉTODOS PARÁMETROS /

ACCESORIOSEVENTOS

GENERADOS POR

ContainerListener ContainerAdapter componentAddedcomponentRemoved

ContainerEventgetChildgetContainer

Container

FocusListener FocusAdapter focusGainedfocusLost

FocusEventisTemporary

Component

KeyListener KeyAdapter keyPressedkeyReleasedkeyTyped

KeyEventgetKeyChargetKeyCodegetKeyModifiersTextgetKeyTextisActionkey

Component

INTERFAZ CLASE ADAPTADORA

MÉTODOS PARÁMETROS / ACCESORIOS

EVENTOS GENERADOS POR

Tabla resumen

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

EVENTOS XIII

Tabla resumen

INTERFAZ CLASE ADAPTADORA

MÉTODOS PARÁMETROS / ACCESORIOS

EVENTOS GENERADOS POR

MouseMotionListener MouseMotionAdapter mouseDraggedmouseMoved

MouseEvent Component

MouseWheelListener mouseWheelMoved MouseWheelEventgetWheelRotationgetScrollAmount

Component

WindowListener WindowAdapter windowClosingwindowOpenedwindowIconifiedwindowDeiconifiedwindowClosedwindowActivatedwindowDeactivated

WindowEventgetWindow

Window

WindowFocusListener windowGainedFocuswindowLostFocus

WindowEventgetOppositeWindow

Window

INTERFAZ CLASE ADAPTADORA

MÉTODOS PARÁMETROS / ACCESORIOS

EVENTOS GENERADOS POR

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

ACCIONES I

El objetivo de las acciones es proporcionar un mecanismo para activar de varias formas un mismo comando. Por ej, a través de un menú, el teclado o un botón de una barra de herramientas. Las acciones evitan tener que enlazar todos los eventos al mismo oyente.

Para poder utilizar las acciones, Swing proporciona la interfaz Action, la cual tiene los siguientes métodos: void actionPerfomed(ActionEvent evento) void setEnabled(boolean b) boolean isEnabled() void putValue(String key, Object value) Object getValue(String key) void addPropertyChangeListener(PropertyChangeListener listener) void removePropertyChangeListener(PropertyChangeListener listener)

La interfaz Action deriva de la interfaz ActionListener (ver que comparten el método actionPerformed). Por tanto, podemos utilizar un objeto Action donde se espere un objeto ActionListener.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

ACCIONES II Los métodos setEnabled y isEnabled permiten activar o desactivar la

acción (muy útil porque atenúan los componentes que usan dicha acción) y comprobar si la acción está activa respectivamente.

Los métodos putValue y getValue permiten guardar y recuperar pares arbitrarios nombre/valor en el objeto acción. Aquí se muestran algunos nombres útiles y su función: NAME: el nombre de la acción. Se muestra en botones y opciones de menú. SMALL_ICON: guarda un icono pequeño. Se muestra en un botón, opción de

menú o barra de herramientas. SHORT_DESCRIPTION: descripción corta. Se muestra como tooltip al

mantener el ratón sobre el componente. MNEMONIC_KEY: método abreviado de teclado. Lo veremos cuando veamos

menús.

Existe una “especie” de clase adaptadora para la interfaz Action que es AbstracAction. No es propiamente una clase adaptadora porque implementa todos los métodos menos el actionPerformed. Además, hace más cosas ya gestiona los pares nombre/valor y los oyentes de propiedad de cambio. Esto último está relacionado con los dos últimos métodos de la interfaz y no lo vamos a ver. Es más importante en JavaBeans.

Métodos y pares nombre/valor

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

ACCIONES III

Para asociar pulsaciones de teclas a las acciones hay que generar objetos de la clase KeyStroke.

Para crear un objeto de este tipo no se llama a un constructor, sino que se llama al método estático getKeyStroke de la clase, que recibe el código virtual de la tecla y los modificadores o una cadena.

Pulsaciones de teclas

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

ACCIONES IV Ahora hay que enlazar los objetos KeyStroke a las acciones. Esto se

hace con tres mapas de entrada y un mapa de acción que tienen todos los objetos JComponent.

Cada mapa de entrada se corresponde con una condición diferente. WHEN_FOCUSED: cuando el componente tiene el foco del teclado. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: cuando el

componente contiene el componente que tiene el foco del teclado. WHEN_IN_FOCUSED_WINDOW: cuando el componente está contenido

en la misma ventana que el componente que tiene el foco del teclado. Un mapa de entrada (clase InputMap) se obtiene con el método

getInputMap del componente, y un mapa de acción (clase ActionMap) se obtiene con el método getActionMap.

Mapas

Esto tiene que ser un “Object”. Usamos una cadena porque es lo más cómodo. Si se pone a null rompemos el enlace.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

ACCIONES V

Ejemplo

La clase principal y el marco que contiene el panel que tiene los botones a los que se asocian las acciones.

Este ejemplo muestra un panel con tres botones que cambian el color de dicho panel. Utilizamos acciones que nos ayudan a mostrar tooltips, a cambiar el color con los botones o con teclas.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

ACCIONES VI

Ejemplo

Mapa de entrada

Mapa de acción

Clase acción que establece los nombre, iconos y descripciones cortas. Además, con e l actionPerformed establecemos lo que realiza la acción (cambiar el color del panel).

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING I Veamos ahora unos cuantos componentes Swing, teniendo

en cuenta alguna cosa: No vamos a verlos todos (ni mucho menos), sino los más

representativos para una determinada función. Los analizaremos someramente y explicando para que sirven.

No se verán a fondo ni estudiaremos sus métodos o propiedades (para eso está la API).

Haremos algún ejemplo intermedio que demuestre su funcionamiento, pero agrupando varios componentes.

Algunos no los veremos aunque se usan constantemente (contenedores como marcos y paneles, botones, etc). Con los ejemplos de las secciones anteriores debería ser suficiente para manejarlos más o menos.

Es importante que durante esta sección tengáis a mano la API y para cada clase consultéis sus constructores, constantes, un vistazo a los métodos, etc.

Introducción

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING II Hay varios componentes útiles a la hora de trabajar con texto:

Etiquetas (JLabel): texto estático. Campos de texto (JTextField): permite la entrada de texto al usuario. Campos de contraseñas (JPasswordField): igual que el anterior pero

con el texto oculto para poder introducir texto “delicado” como contraseñas.

Áreas de texto (JTextArea): para introducir grandes cantidades de texto. Hay otros componentes más avanzados y muy útiles, con otras

funcionalidades (soportan estilos, permiten objetos embebidos, etc), como los JEditorPane o JTextPane.

Entrada de texto

Campo de texto

Área de texto

Campo de contraseña

Etiqueta

JEditorPane

JTextPane

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING III Cuando tenemos que realizar una selección, dependiendo de

la necesidad podremos usar alguno de estos componentes: Casillas de verificación (JCheckBox): se usan para obtener una

entrada de tipo “sí” o “no”. Botones de radio (JRadioButton): se usan para que el usuario

seleccione una sola opción de varias disponibles. Se agrupan en objetos de tipo ButtonGroup.

Cuadros combinados (JComboBox): misma finalidad que los radio buttons pero para ofrecer más opciones. Además ofrecen la opción de hacerlas editables y seleccionar una opción que inicialmente no existe.

Existen otros como listas (JList), deslizadores (JSlider) y spinners (JSpinner).

SeleccionesEdi

tabl

e

No ed

itabl

e

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING IV La construcción de menús, aunque puede llegar a ser muy

elaborada, precisa de tres clases básicas: Barra de menú (JMenuBar): en ella se sitúa el menú. Menús (JMenu): Son los elementos principales, de los que

“cuelgan” items. Elementos o items de menú (JMenuItem): son los elementos

finales, los que se seleccionan. A los menús se les pueden añadir items que sean checkboxes

o radio buttons, así como iconos, métodos abreviados, teclas aceleradoras, etc. Es muy útil gestionarlos con acciones.

Menús

JMenuBar

JMenu

JMenuItem

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING V Vamos a realizar dos clasificaciones de los cuadros

de diálogo: Cuadros de diálogo predefinidos: la API nos proporciona

clases y métodos para generar cuadros de diálogo predefinidos muy útiles en la mayoría de las ocasiones. Clase JOptionPane: cuadros de diálogo para mensajes,

confirmaciones, opciones básicas y obtención de información también muy básica.

Selectores de ficheros (JFileChooser): para entrada/salida con el sistema de ficheros.

Selectores de color (JColorChooser): para elegir colores. Muestra paletas y configuraciones de colores.

Cuadros de diálogo creados por el programador (clase JDialog): permiten al programador generar sus propios diálogos personalizados con todos los elementos que sean necesarios. Hay dos tipos: Modales: bloquean el resto de ventanas hasta que se

cierran. No modales: permiten seguir trabajando con el resto de

ventanas aún cuando están abiertos.

Cuadros de diálogo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING VI La clase JOptionPane ofrece cuatro métodos para generar

cuadros de diálogo predefinidos: showMessageDialog: muestra un mensaje y espera a que el

usuario pulse OK. showConfirmDialog: muestra un mensaje y obtiene

confirmación (del estilo OK/Cancel). showOptionDialog: muestra un mensaje y obtiene una opción

de una serie de opciones. showInputDialog: muestra un mensaje y obtiene una línea de

entrada del usuario.

Estos cuadros de diálogo tienen un icono, un mensaje, uno o más botones de opciones y opcionalmente (dependiendo del tipo), un cuadro de texto para la entrada de información.

El mensaje puede ser una cadena, un icono, un componente o cualquier otro objeto.

Cuadros de diálogo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING VIII

Los selectores de ficheros y de colores son muy versátiles y con multitud de opciones. Consultar la API.

Cuadros de diálogo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING IX Podemos crear nuestros propios cuadros de diálogo

personalizados. Para ello tendremos que derivar de la clase JDialog.

Para crear un cuadro de diálogo, solo tendremos que indicarle cual es su marco propietario (puede ser null), su título y si es modal o no modal.

Por lo demás su funcionamiento es muy similar a un JFrame.

Una de las cosas más importantes es controlar bien el intercambio de datos con los cuadros de diálogo (normalmente para eso se utilizan). Para esto se suele implementar en la clase del diálogo un método que muestra el cuadro de diálogo y devuelve el estado de una variable booleana que indica si el cuadro se ha aceptado (hay que recoger los datos) o se ha cancelado (no se hace nada).Ver ejemplo IntercambioDatos.java

Cuadros de diálogo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING X Hay varios componentes para mostrar datos de diferentes

tipos. Los dos más utilizados son las tablas y los árboles. Ambos son componentes avanzados. Nos obligan a trabajar

directamente con su modelo (recordar el MVC). Las tablas (JTable) nos sirven para mostrar datos en una

rejilla y, opcionalmente, permitir al usuario modificar los datos. Un objeto de esta clase no contiene datos, solo nos sirve como vista de los datos, los cuales gestionaremos a través de su modelo.

Los árboles (JTree) nos sirven para mostrar datos jerárquicos. Un objeto de esta clase no contiene datos, solo nos sirve como vista de los datos, los cuales gestionaremos a través de su modelo.

Mostrar datos

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

COMPONENTES SWING XI

Aún hay otros cuantos componentes Swing interesantes cuyo funcionamiento podéis consultar en la API y en el tutorial de Java de Sun: Marcos internos: para escribir aplicaciones tipo MDI Windows.

(Ver ej, libreria.java). Barras de herramientas: permiten colecciones de botones con

iconos para tener acceso rápido a determinadas opciones (tendréis que utilizarlas vosotros en un ejemplo).

Barras de progreso: para indicar progresos en determinadas acciones.

Paneles de desplazamiento: añaden barras de desplazamiento a los componentes. Los veremos en numerosos ejemplos.

Separadores: nos permiten dividir un contendor en partes y añadir componentes a cada parte.

Paneles tabulados: permiten crear varios paneles ocupando el mismo espacio que pueden seleccionarse mediante pestañas.

Bordes: permiten añadir bordes a paneles y otros contenedores. Iconos e imágenes: no se si hay mucho que explicar.

Otros componentes

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Pintando en AWT y SWING

• Qué es y cómo se pinta• Callbacks• Clases importantes:

– Graphics

• Api Java 2D

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Pintar en un sistema de ventanas

• Pintar es renderizar un conjunto de bits a una pantalla u otro dispositivo.

• Lo importante es pintar lo correcto en el momento justo.

• Hay dos tipos de peticiones de pintar:– Peticiones por parte del sistema a una componente:

• La primera vez que se visualiza.

• El componente se redimensiona.

• El componente se ha deteriorado (estaba oculto).

– Peticiones por parte de la aplicación: el estado interno de la componente ha cambiado.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Peticiones del sistema: el método paint

Public void paint (Graphics g)

• Es un método callback, el programador lo redefine pero es llamado por el sistema. Está en Component.

• Cuando el sistema llama a paint, el objeto g se configura para contener el estado adecuado para pintar la componente: color, font, translation (coordenadas), clip Rectangulo (zona a pintar), ...

• La operación toma lugar en dos pasos:

– Determinar la zona a pintar.

– Provocar que el hilo de despacho de eventos invoque paint()

• Ejemplo PaintDemo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Peticiones de aplicación: el método repaint

Public void repaint ()

Public void repaint (int x, int y, int width, int height)

...

• Es el método que el programador debe invocar para provocar un pintado. No debe llamar directamente a paint().

• En repintados complejos debería evitarse el repintado completo y definir la zona a repintar.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

El método update

• El repintado por parte de la aplicación requiere de 4 pasos:

– Determinar por parte de la aplicación la zona a repintar.

– Invocar a repaint().

– El hilo de despacho de eventos invoca a update().

– Si no se ha redefinido update(), su efecto es borrar el fondo de la comp. y llamar a paint().

• Puede redefinirse update() y aprovechar esa llamada intermedia.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Componentes pesadas y ligera

• Componentes pesadas: disponen de ventana propia.

• Componentes ligeras: no disponen de ventana propia. Usan la de su ancestro.

• Desde el punto de vista del programador casi no hay diferencias a la hora de repintar unas u otras.

• Las componentes pesadas que se deben repintar lanzan paints a todos sus decendientes ligeros.

• Si una clase desciende de Container y redefine paint(), debe invocar como última llamada: super.paint().

• Las componentes ligeras soportan transparencia.

• Las componentes pesadas soportan repintado incremental

Ejemplo LightweightDemo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Pintando en SWING

• Usa el modelo básico de AWT.• Añade doble buffering.• Gestión de borders y delegación de

interfaz de usuario.• Facilita un RepaintManager.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Doble buffering

• Consiste en pintar en memoria primero y enviar posteriormente a pantalla. Evita el excesivo repintado en pantalla.

• SWING lo soporta directamente mediante la propiedad doubleBuffered en javax.swing.JComponent.

public boolean isDoubleBuffered()

public void setDoubleBuffered(boolean o)

• Cuando se activa en una componente, se activa en todos sus descendientes ligeros.

• Por defecto está asignada a true para todas las componentes Swing.

• No requiere ningún trabajo adicional por parte del programador.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Los métodos paint

• En Swing el método paint se factoriza en tres llamadas:

protected void paintComponent(Graphics g)

protected void paintBorder(Graphics g)

protected void paintChildren(Graphics g)

• El programador debería redefinir paintComponent en vez de paint().

• Eso soluciona el problema de llamar a super.paint()

• Ejemplo SwingPaintDemo

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Opacidad

• Propiedad de Jcomponent:

public boolean isOpaque()

public void setOpaque(boolean o)

True: el componente pinta todos los bits contenidos en sus límites.

• False: no garantiza pintar todos sus bits.

• El valor por defecto depende del look and feel IU, pero es true para la mayoría.

• Permite determinar al sistema si componentes antecesoras deberán ser repintadas.

• Permite transparencias, pero es más costosa computacionalmente.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Pintado optimizado

• Una componente puede ser solapada por otra que no es una antecesora suya (una sobrina, prima o tía)

• Si Swing tuviese que recorrer todo el árbol de componentes relacionadas con una que debe ser repientada sería muy ineficiente.

• La propiedad

isOptimizedDrawingEnabled

• le indica a Swing (si es true) que ninguna componente solapa a la que tiene que ser repintada.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

La clase Graphics

• Contiene métodos para dibujar y rellenar formas básicas, (líneas, rectángulos, óvalos) texto e imágenes.

• Contiene atributos que afectan a como se dibuja y rellenan objetos. (color, pen, relleno, font, composición, transformación ...)

• La clase Component tiene un método getGraphics que crea un contexto gráfico para la componente.

• Ver api de Java o tutorial Java 2D

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Imágenes

• Clase para manejar imágenes:java.awt.image.BufferedImage

• Se pueden crear imágenes desde el programa, dibujar imágenes en pantalla, cargar imágenes de ficheros y salvar imágenes a ficheros.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Carga de imágenes

BufferedImage img = null;

try {

img = ImageIO.read(

new File("strawberry.jpg"));

} catch (IOException e) {

}

Formatos admitidos: jpeg, png, gif bmp, wbmp

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Dibujando una imagen

boolean

Graphics.drawImage(Image img,

int x, int y,

ImageObserver observer);

x, y da la posición (esquina sup-izq) de la imagen.

• Observer es para cargar imágenes asíncronamente. Poner a null.

• DrawImage está sobrecargado con muchos otros métodos que posibilitan dibujar parte de la imagen, escalar, cubrir parte, o filtrar la imagen.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Creando y dibujando una imagen

• Usar los constructores de BufferedImage.

• Usar los métods de la clase Component como createImage u otros. Estos métodos analizan la resolución de la pantalla para un componente y crear una imagen apropiada.

• Usando createGraphics() de BufferedImage. Permite usar una imagen como una superficie de dibujo.

• Java 2D permite acceder a la aceleración hardware para imágenes en memoria.

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

Grabando una imagen

try {

BufferedImage bi = getMyImage(); // retrieve image

File outputfile = new File("saved.png");

ImageIO.write(bi, "png", outputfile);

} catch (IOException e) {

...

}

Creando GUIs con JFC/SWING

Adol

fo R

. de

Soto

Car

los

Test

era

Con

rado A

. Cap

dev

ila

REFERENCIAS

http://java.sun.com The Java tutorial: Swing, Java 2D Java 2. Volumes I and II. Prentice Hall

and Sun Microsystems. JavaDoc y API Java 5.0 Painting in AWT and SWING. SDN

network.