Download miswing

Document related concepts
no text concepts found
Transcript
Java GUI
La librería Swing
//java.sun.com/docs/books/tutorial/uiswing
//programacion.com/java/tutorial/swing/
Programación conducida por
eventos
 En programas tradicionales (basados en texto):
 el programa controla el flujo de la ejecución
 el programa controla la secuencia de las entradas
 Los programas con GUI son “event-driven”
 la secuencia de las entradas controlan el flujo de la
ejecución
 el sistema invoca código del usuario
Programación conducida por
eventos
Código
del
sistem
a
Su código
Generación de eventos
1. Las acciones tales como: pulsar un botón, mover el
mouse, etc. son reconocidas e identificadas por los
sistemas operativos (OS) o la JVM.
2. Por cada acción el OS/JVM determinan cuál de los
programas que se están ejecutando recibirán la señal
(de la acción).
3. Las señales que la aplicaciones reciben del OS/JVM como
resultado de una acción son llamadas eventos.
Generación de eventos
GUI
Acciones Mouse, Teclado,etc.
Sistema Operativo
JAVA API /Windows
Métodos y handlers
Aplicación 1
Eventos
Métodos y handlers
Aplicación 2
Manejo de eventos
 Una aplicación responde a los eventos ejecutando
código adecuado para cada tipo particular de eventos.
 No todos los eventos necesitan ser tenidos en cuenta por
una aplicación. Por ejemplo: Una aplicación para dibujar
puede estar interesada sólo en movimientos del mouse.
 Como diseñador de una aplicación manejada por eventos,
deberá escribir clases/métodos para manejar los eventos
relevantes.
Java GUI
 Java provee dos librerías para crear GUIs:
 Java AWT (Abstract Window Toolkit)
 Java Foundation Classes (JFC o Swing), a
partir de Java2
Java Foundation Classes
 JFC es una colección muy
grande de software.
 AWT y Swing son las dos
grandes familias para
desarrollo de GUI en
el entorno Java.
AWT
Swing
Drag & Drop
JFC APIs
2D API
Accessibility
Java Foundation Classes
Swing
 Implementada sin usar código nativo (100% Java),
con lo cual la GUI se verá de la misma forma
en distintas plataformas.
 Basada en la arquitectura MVC.
 Ofrece una amplia variedad de Look & Feel.
 Los componentes de Swing continuarán siendo
mejorados en el futuro.
AWT y Swing
 Los componentes de Swing tienen nombres que
comienzan con J.
 Ejemplo: Button en AWT es JButton en Swing
 Los componentes de AWT están en el paquete
java.awt, los de Swing en javax.swing.
 import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
Paquetes JFC/Swing
• javax.swing
•
•
•
•
javax.swing.plaf
javax.swing.plaf.basic
javax.swing.plaf.metal
javax.swing.plaf.multi
• javax.swing.table
• javax.swing.tree
• javax.swing.border
• javax.swing.colorchooser
• javax.swing.filechooser
•
•
•
javax.swing.text
javax.swing.text.html
javax.swing.text.html.parser
•
javax.swing.text.rtf
• javax.swing.event
• javax.swing.undo
Paquetes JFC/Swing
Control del
“Look & Feel”
de Swing
Widgets basados en texto
( incluyendo html/rtf )
Componentes,
incluyendo
componentes
complejos
Paquetes nuevos de eventos
Aplicaciones basadas en GUI
 El desarrollo de una aplicación basada en GUI
requiere la comprensión de:
 Estructura de la jerarquía de herencia, que define
el comportamiento y atributos de los componentes
en la GUI de la aplicación.
 Estructura de la jerarquía de contenedores, que
define cómo se disponen todos los componentes
en la GUI de la aplicación.
 Manejo de eventos.
Jerarquía de Herencia
Herencia “Heavy”
java.awt.Window
java.awt.Panel
java.applet.Applet
JApplet
java.awt.Dialog
JDialog
JWindow
JFrame
Heavyweight vs. Lightweight
Contenedores en Swing
java.aw t.Container
JMenu
JMenuBar
JComponent
JLayeredPane
JRootPane
JPanel
JTabbedPane
JDesktopPane
JSplitPane
JPopupMenu
JOptionPane
JInternalFrame
JToolbar
JScrollPane
Similar a
AWT
Nuevos
de Swing
Componentes de Swing
 La clase Component (y sus subclases) proveen soporte
para manejo de eventos, cambio del tamaño de un
componente, control de color y fuentes, pintado.
 Un componente es un objeto de una subclase concreta.
Se distinguen dos clases de componentes:
 Componentes de control de la GUI: la interacción
de la GUI con el usuario se realiza a través de ellos.
 Contenedores: contienen otros componentes (u otros
contenedores).
Contenedores
 Anidamiento de componentes (Jerarquía de contenedores
en contraste con la Jerarquía de herencia). Cada
programa Swing contiene al menos una.
 Usan un Layout Manager para determinar cómo se
disponen los componentes en los contenedores.
 Swing provee 4 contenedores de alto nivel (ventana
base de la GUI): JFrame, JApplet, JDialog y JWindow.
 La jerarquía está compuesta de diferentes capas.
Cada contenedor de alto nivel contiene un contenedor
intermedio conocido como “content pane ”. En casi todos
los programas no es necesario conocer qué hay entre el
contenedor de alto nivel y el content pane.
Jerarquía de contenedores
Jerarquía de contenedores
 La apariencia de una GUI está determinada por:
 La jerarquía de contenedores
 El Layout Manager de cada contenedor
 Las propiedades de los componentes individuales
 Todos estos ítems trabajan en conjunto para determinar
el efecto visual final.
Estructura de un JFrame
Estructura de un JFrame
Root Panes
 “Añadido” en forma invisible al contenedor de alto nivel.
 Creado por Swing cuando instancia un contenedor de alto
nivel.
 Maneja prácticamente todo entre el contenedor de alto
nivel y los componentes atómicos.
 Tener en cuenta si necesita interceptar clicks del mouse o
pintar sobre varios componentes.
 Es una instancia de JLayeredPane la que contiene la barra
de menús y el content pane.
Content Panes
 Usualmente es un JPanel.
 En la mayoría de las aplicaciones Swing contiene casi
todo, excepto la barra de menú.
 Debe ser creado explícitamente.
Layered Panes
 Provisto por root pane pero también puede crearse.
 Contenedor con profundidad, tal que componentes
que se superponen (ej:popup menus) pueden aparecer
unos encima de otros (z-buffering).
Glass panes
 Util para pintar o interceptar eventos (por ejemplo:
bloquear todos los eventos del mouse) en un área que
contenga uno o más componente
Contenedores de alto nivel
Applet
Dialog
Frame
Contenedores generales
Panel
TabbedPane
Scroll Pane
SplitPane
Toolbar
Contenedores especiales
InternalFrame
Root Pane
LayeredPane
JFrame
Algunos métodos de JFrame
 Para añadir componentes al content pane:
myFrameInstance.getContentPane().add(myComponent);
Usual
“this”
Requerido por
Instancias de
JFrame,
JDialog y
JInternalFrame
Ej.:
“myLabel”
Algunos métodos de JFrame
 Para construir una ventana con un título y mostrarla:
JFrame theWindow = new JFrame( "Graffiti" );
theWindow.show( );
//idem theWindow.setVisible(true);
 Para determinar su tamaño:
theWindow.setJMenuBar(cyanMenuBar);
theWindow.setSize( 220, 100 );//o mejor
theWindow.pack();
Nueva funcionalidad de
JFrame
 setDefaultCloseOperation(int) es la más importante:
 DO_NOTHING_ON_CLOSE
 HIDE_ON_CLOSE (default) oculta el frame cuando el
usuario lo cierra pero no se deshace de los recursos del
sistema asociados (puedo volver a mostrar).
 DISPOSE_ON_CLOSE oculta el frame y llama al
método dispose(), para liberar recursos.
 EXIT_ON_CLOSE, cierra la aplicación (System.exit(0))
Hello World en Swing
import javax.swing.*;
public class HelloWorldSwing {
public static void main(String[] args) {// crear un nuevo frame
JFrame frame = new JFrame("HelloWorldSwing");
// crear una etiqueta y añadir al frame
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
//especifica la operación de cierre de la ventana
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// muestra el frame en pantalla
frame.pack(); frame.setVisible(true);}}
Componentes atómicos
 Componentes de tipo JPanel almacenan otros objetos
de la GUI tales como: botones, etiquetas,
campos de texto, etc. Estos objetos gráficos son
considerados componentes atómicos, puesto que no
pueden almacenar otros objetos de la GUI.
Componentes atómicos
básicos
Buttons
Menu
Combo Box
Slider
Spinner
List
Text Fields
Componentes atómicos no
editables
Label
Progress Bar
Tool tip
Otros componentes atómicos
Color Chooser
Table
File Chooser
Text
Tree
API de los componentes GUI
 Componente GUI en Java= class
 Propiedades
 Métodos
 Eventos
JButton
Componentes GUI
1.- Crear
 Instanciar objeto: b = new JButton(“press me”);
2.- Configurar
 Propiedades: b.text = “press me”; (evitar en Java)
 Métodos:
b2 = new JButton("Middle button", middleButtonIcon);
b2.setVerticalTextPosition(AbstractButton.BOTTOM);
b2.setHorizontalTextPosition(AbstractButton.CENTER);
b2.setMnemonic(KeyEvent.VK_M);
b2.setToolTipText("This middle button does nothing “
+ "when you click it.");
3.- Añadir
 panel.add(b);
4.- Manejar eventos
Características especiales
 Los componentes Swing ofrecen características especiales:
Tool tip
Cuando el cursor del mouse se detiene
sobre un componente se muestra una
línea de texto.
Mnemonic
Se ejecuta una acción como resultado del
pulsado de una combinación de teclas.
Un componente puede ser explícitamente
habilitado o deshabilitado.
Rodea un componente con un borde.
Disable
Border
Características especiales
 Tool tips
JButton button = new JButton ("Compute");
button.setToolTipText ("Calculate size.");
 Mnemonic
button.setMnemonic ("C");
 Disable
JButton button = new JButton (“Do It”);
button.setEnabled (false);
Características especiales
 Bordes
JPanel myPanel = new JPanel();
Border myBorder = BorderFactory.createEtchedBorder();
myPanel.setBorder(myBorder);
 Empty
 Titled
 Line
 Matte
 Etched
 Compound
 Bevel
Bordes
Anatomía de una aplicación
GUI
JFrame
JFrame
JPanel
contenedores
JPanel
JButton
JButton
JLabel
JLabel
Estructura interna
GUI
Uso de un componente GUI
1. Crearlo
2. Configurarlo
3. Añadir hijo (si es contenedor)
4. Añadir al padre (si no es JFrame)
5. Manejar los eventos
orden
importante
Construcción bottom up
Listener
 Crear:
 Frame
 Panel
JLabel
JButton
 Componentes
 Listener
JPanel
 Añadir (bottom up)
 Listeners a los componentes
 Componentes al panel
 Panel al Frame
JFrame
Window Layout
contenedores
componentes
Window Layout
 Cada contenedor maneja la disposición de sus
componentes.
 El programador sólo añade componentes, el contenedor
se encarga de la disposición de los mismos.
 El contenedor usa un Layout Manager para manejar
la disposición de los componentes en el mismo.
 Están disponibles diferentes Layout Managers.
 El layout puede ser determinado especificando Layout
Managers para los contenedores.
Layout Managers
 Hay varios Layout Managers predefinidos en:
 FlowLayout
(en java.awt)
 BorderLayout (en java.awt)
 CardLayout
(en java.awt)
 GridLayout
(en java.awt)
 GridBagLayout (en java.awt)
 BoxLayout
(en javax.swing)
 OverlayLayout (en javax.swing)
Layout Managers (LM)
 Cada contenedor tiene un Layout Manager por defecto, aunque
se puede establecer otro LM para el mismo, de forma explícita.
Para anular el LM por defecto se usa el método setLayout (para
contenedores de alto nivel se usa getContentPane().setLayout().
 El Layout Manager intenta ajustar la disposición de los
componentes en el contenedor cuando se añade un nuevo
componente o cuando el contenedor cambia de tamaño.
 Puede crear su propio LM.
Layout Managers de AWT
null
FlowLayout
ninguno,
programador
setea x,y,w,h
Left to right,
Top to bottom
BorderLayout
n
w
c
s
e
CardLayout
One at a time
GridLayout
GridBagLayout
JButton
Null Layout
 setLayout(null);
 El programador es responsable de establecer el tamaño y
posición de cada componente (setBounds(x,y,w,h))
Combinaciones
JButton JButton
JTextArea
Combinaciones
JButton
JButton
JFrame
n
JPanel: FlowLayout
JPanel: BorderLayout
c
JTextArea
Tareas comunes del LM
 Prestar atención a indicaciones de un componente:
 de tamaño:
setMinimumSize(Dimension), setPreferredSize(..), setMaximumSize(..)
 de alineamiento:
setAllignmentX(float), setAlignmentY(float)
 Poner espacios entre componentes:
 el LM puede especificar hgap y vgap
 poner componentes invisibles
 bordes vacíos: para componentes que no tienen
bordes por default, por ej.:JPanel, JLabel.
Estructura del Layout
JPanel(BoxLayout(V))
label
rigidArea(0,5)
Center
JScrollPane
South
HorizontalGlue
JPanel (BorderLayout)
JButton
JButton
JPanel(BoxLayout(H))
rigidArea(10,0)
FlowLayout
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(new JButton("Button 1"));
 Es el LM por defecto de JPanel.
 Dispone los componentes de izquierda aderecha a medida que
se añaden, comenzando filas nuevas si es necesario.
FlowLayout
 Cada fila de componentes está centrada por defecto,
pero puede alinearse por derecha o izquierda.
 Pueden establecerse explícitamente espacios verticales
y/o horizontales entre componentes.
 Usar sólo en aplicaciones muy simples (oculta
componentes que no entran).
GridLayout
Container contentPane = getContentPane();
contentPane.setLayout(new GridLayout(0,2));//tantas filas como necesita
contentPane.add(new JButton("Button 1"));
 Dispone los componentes en forma de matriz, con la cantidad
de filas y columnas especificadas.
 Todas las filas tienen el mismo alto y todas las columnas tienen
el mismo ancho. El tamaño de cada celda es determinado por el
tamaño del contenedor. Permite establecer vgap y hgap.
 Usar si es seguro que los componentes tendrán igual tamaño.
BorderLayout
Container contentPane = getContentPane();
contentPane.add(new JButton("Button 1 (NORTH)"),BorderLayout.NORTH);
//no hace falta setear el LM
 Es el LM por defecto de los content pane (contenedor principal
en JFrame, JDialog y JApplet).
 Define 5 áreas en las cuales se pueden añadir los componentes.
BorderLayout
 Si se agranda la ventana, la parte central toma tanto espacio
como le sea posible, las otras 4 áreas se expanden sólo lo
necesario para llenar el espacio disponible.
 Un contenedor, generalmente usa 1 o 2 de las 5 áreas de
BorderLayout. Por ejemplo: centro o centro y sur. Se puede
especificar vgap y hgap.
CardLayout
Jpanel cards = new JPanel();
cards.setLayout(new CardLayout());
cards.add(p1, "JPanel with JButtons");
 Permite implementar un área que contiene distintos
componentes en distintos instantes de tiempo (naipes).
 Normalmente controlado por una Combo Box, el estado de ésta
determina cuál grupo de componentes muestra el LM.
GridBagLayout
Container contentPane = getContentPane();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
contentPane.setLayout(gridbag);
c.fill = GridBagConstraints.HORIZONTAL;
Jbutton button = new JButton("Button 1");
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
gridbag.setConstraints(button, c);
 Es el LM más sofisticado y
flexible. Alinea componentes
en una matriz de celdas
permitiendo a algunos
componentes abarcar más
de una celda.
BoxLayout
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
buttonPane.add(Box.createHorizontalGlue());
buttonPane.add(cancelButton);
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPane.add(setButton);
 Pone los
componentes en
una sola fila o
una sola columna
 Respeta los tamaños máximos requeridos de los componentes
y el alineamiento X/Y.
BoxLayout
 Los componentes son dispuestos de arriba abajo o de
izquierda a derecha en el orden en el cual son añadidos al
contenedor.
 Pueden crearse muchas configuraciones distintas, combinando
múltiples contenedores que usen BoxLayout.
 Preferido a un único contenedor que use el más complicado
GridBagLayout (mejor: BoxLayouts anidados), es útil también
en algunas situaciones donde se podría considerar el uso de
GridLayout o BorderLayout.
BoxLayout
 BoxLayout tiene en cuenta el alineamiento, tamaños
mínimos, máximos y preferidos que se eligen para los
componentes:
btn.setAlignmentX(float alignmentX);
lbl.setAlignmentY(float alignmentY);
lbl.setMaximumSize(new Dimension(int width, int height);
lbl.setMinimumSize(new Dimension(int width, int height);
lbl.setPreferredSize(new Dimension(int width, int height);
 Para añadir espacio entre componentes se usa la clase Box
o bordes invisibles a uno o ambos componentes.
BoxLayout
Tipo
Rigid area
Tamaño
Cómo crearla?
Box.createRigidArea(size)
horizont
al
Box.createHorizontalGlue()
vertical
Box.createVerticalGlue()
customBox.Filler
new Box.Filler(minSize,
prefSize, maxSize)
Glue
Otras estrategias Swing
 JSplitPane
 JTabbedPane (CardLayout)
 JToolBar
Pasos en el desarrollo de una
aplicación simple con GUI
 Extienda la aplicación de JFrame
 Declare las referencias a componentes necesarios
 Defina el constructor
 Instancie un content pane y decida Layout
 Instancie objetos para los componentes necesarios y establezca sus
propiedades
 Añada al objeto content pane
 Añada los listeners de los componentes y defina código
del método actionPerformed
 Añada un método main() que instancie el objeto creado y tome los
recaudos para cerrar la ventana
Pintado
 Cuando la GUI necesita cambiar su apariencia visual
se pinta en la pantalla, comenzando siempre desde el
contenedor de alto nivel (Ej.: JFrame o JApplet) y
procediendo de esta forma hacia abajo en la jerarquía
de contenedores
 El pintado es double-buffered por eficiencia
 Los componentes Swing normalmente se repintan ellos
mismos en forma automática
 Paint se ejecuta en el event-dispatching-thread
Pintado
Los componentes se pintan automáticamente
Todo lo
demás:Programador
JButton
Cuándo se pinta?
 Pintado disparado por el sistema (se invoca paint())
 La primera vez que el componente es visible
 Cuando un componente es cubierto y luego descubierto
 Cuando es necesario reflejar un cambio en el estado del
programa
 Pintado disparado por la aplicación
 Cuando cambia texto, colores,etc.
 Cuando desea repintar (invoca a repaint(), no a paint()
que pone en la cola este requerimiento)
 El thread de manejos de eventos llama a paint() del
componente
Pintado
 Pintado de un componente que extiende JComponent
1.fondo
(si es opaco)
2. custom
painting (si hay)
3. borde
(si hay)
4. hijo
(si tiene)
Pintado custom
Nunca llamar
paint()
directamente.
Llamar repaint()
JComponent
paint paintComponent
paintBorder
paintChildren
extends
paint
JPanel
paintComponent
paintBorder
paintChildren
extends
PaintPanel
paint paintComponent
paintBorder
paintChildren
El método
correcto a
anular en
pintado custom
Pintado
 Qué ocurre cuando se invoca paint()?
paint(Graphics g)
paintComponent(Graphics g)
paintBorder(Graphics g)
paintChildren(Graphics g)
 Antes de hacer cualquier cosa en paintComponent(...):
 invoque super.paintComponent (pinta background)
Pintado
 Cada componente tiene su propio sistema de coordenadas
desde (0,0) hasta (ancho-1, alto-1)
(0, 0)
X
Component
(ancho -1, alto -1)
Pintado
 Tener en cuenta el borde del componente (si lo tiene),
reduce el área de pintado y desplaza coordenadas.
Objeto Graphics
 El objeto Graphics provee un contexto para el pintado y
métodos para la misma función.
 El contexto gráfico consiste en el estado actual:color de
pintado, fuente, área de pintado
Pintado de formas
 La clase Graphics define métodos para pintar formas:
 void drawLine(int x0, int y0, int x1, int y1)
 void drawArc(int x, int y, int width, int height, int startAngle,int
arcAngle)
 void drawPolygon(Polygon p)
 void drawPolygon(int xPoints[ ], int yPoints[ ], int numPoints)
 void drawRect(int x, int y, int width, int height)
 void drawRoundRect(int x, int y, int width, int height, int
arcWidth, int arcHeight)
 void draw3DRect(int x, int y, int width, int height, boolean
raised)
 void drawOval(int x, int y, int width, int height)
Pintado de formas
Pintado de texto
 La clase Graphics define métodos para pintar texto:
String (drawString)
Pintado de texto
 La clase Graphics define métodos para pintar texto:
String (drawString)
Imágenes
 Cargar y mostrar imágenes es muy simple
 Class ImageIcon de javax.swing.
 Ej.:ImageIcon myIcon=new ImageIcon(“imagefile.gif”);
Image image3 = getImage( new
URL("http://java.sun.com/graphics/people.gif"));
Imágenes
•
ImageIcon myImage = new ImageIcon("book.gif");
•
JLabel myLabel = new JLabel(myImage);
•
getContentPane().add(myLabel);
•JButton
JButFeedback = new JButton(myImage);
•JButton
JButWrite = new JButton("Write");
•JButWrite.setIcon(myImage2);
•JButton
JButChange = new JButton(myImage3);
•JButChange.setRolloverEnabled(true);
•JButChange.setRolloverIcon(myImage4);
Carga de imágenes
 myImage =
Toolkit.getDefaultToolkit().getImage(filenameOrURL);
retorna inmediatamente, no hay que esperar que la imagen se
cargue antes de realizar otras operaciones. Algunos programas
requieren más control o información acerca de la carga:
 clase MediaTracker
 método imageUpdate de la interface ImageObserver (útiles
ambas también para no mostrar una imagen hasta que esté
completamente cargada o informar a ProgressBar)
Mostrar imágenes
 Métodos gráficos:(invocar en paintComponent)
 drawImage(image, x, y, observer)
 drawImage(image, x, y, w, h, observer)
 drawImage(image, x, y, bgcol, observer)
 drawImage(image, x, y, w, h, bgcol, ob.)
La clase Component implementa la interface
ImageObserver, casi siempre el último argumento
es this
Imágenes
class MyPanel extends JPanel {
private ImageIcon myImage;
public MyPanel() {
myImage = new ImageIcon("nasa.gif");
setPreferredSize(new
Dimension(myImage.getIconWidth(), myImage.getIconHeight()));
}
public void paintComponent(Graphics g) {
g.drawImage(myImage.getImage(), 10, 10, null);
}}
Imágenes
Animación
 Se muestran sucesivos frames a una velocidad
relativamente alta (usualmente 10-20 frames
por segundo), se crea una sensación de movimiento
 Para actualizar periódicamente la pantalla se usa un
“loop de animación”, normalmente se implementa con
un objeto javax.swing.Timer (se necesita un thread
separado, nunca poner en paintComponent ya que la
aplicación queda congelada)
Animación
 Timer
Timer timer = new Timer(delay, this);
…//this:action handler
public synchronized void startAnimation() {
if (!timer.isRunning()) {timer.start();}
} …
public synchronized void stopAnimation() {
if (timer.isRunning()) { timer.stop();}}