Вы находитесь на странице: 1из 17

Tcnicas avanzadas de programacin

Aplicaciones


Ramiro Lago



2
Introduccin (I)
Sun cre para Java una librera para la creacin de aplicaciones y applets con GUI: AWT. Todos los
navegadores dan soporte por defecto para esta librera.
Debido a las limitaciones de AWT, en la versin 1.1 se cre la librera SWING, a la que no da soporte
por defecto el navegador Microsoft Explorer
Toda aplicacin SWING tiene al menos una ventana principal del tipo JFrame. Un ejemplo
mnimo:
import java.awt.*;
import javax.swing.*;

/******************************************************************************
* Las aplicaciones Java tienen como ventana principal una clase que hereda de JFrame.
*****************************************************************************/
public class Marco extends JFrame {

/***************************************************************************
* El constructor llama a jbInit() para inicializar componentes
***************************************************************************/
public Marco() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK); // Acepta eventos AWT
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}

/***************************************************************************
* Configuracin de ventana e inicializar componentes
***************************************************************************/
private void jbInit() throws Exception {
// this.setSize( new Dimension( 600, 400 ) );
this.setTitle("Ttulo de la aplicacin");
}

}
3
Introduccin (II)
La aplicacin requiere:
Un punto de entrada en la ejecucin: main()
Hacer una instancia del JFrame
import java.awt.*;

public class Inicio {
/***************************************************************************
* Construye la aplicacin
***************************************************************************/
public static void main(String[] args) {
try {
//// Creamos JFrame con estilo y operacin de cierre
Marco frame = new Marco();
javax.swing.JFrame.setDefaultLookAndFeelDecorated(true);
frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE);

//// Centra la ventana principal
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = new Dimension( screenSize.width/2, screenSize.height/2 );
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setSize(frameSize.width, frameSize.height);

// frame.pack(); // Su tamao se cie a preferred size y al tamao de subcomponentes

frame.setVisible(true);

}
catch(Exception e) {
e.printStackTrace();
}
}
}

4
Mens (I)
Para hacer un men
(http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html) no hay mas
que usar las clases:
JMenuBar: barra de men Principal
Jmenu: un men
JMenuItem: una opcin de men
Con JRadioButtonMenuItem y JCheckBoxMenuItem podemos usar opciones del estilo
RadioButton o CheckBox
Para una lnea separadora tenemos JMenu.addSeparator();
Estos objetos los manejaremos como atributos, tanto los objetos de men como los
String para ttulos (aunque en un diseo ms acertado los ttulos estaran en un archivo
properties):
public class Marco extends JFrame implements ActionListener {
JMenuBar menuPrincipal = new JMenuBar(); // MenuBar

//// Men Archivo
JMenu menuArchivo = new JMenu();
JMenuItem menuItemSalir = new JMenuItem();

//// Man Ayuda
JMenu menuAyuda = new JMenu();
JMenuItem menuItemAcercaDe = new JMenuItem();

//// Cadenas de opciones de men
final String ITEM_ARCHIVO = "Archivo";
final String ITEM_AYUDA = "Ayuda";
final String ITEM_ACERCADE = "Acerca de";
final String ITEM_SALIR = "Salir";
.
5
Mens (II)
Desde jbInit() configuramos el men:
private void jbInit() throws Exception {
this.setTitle("Ttulo de la aplicacin");
definirMenu()
}
Los JMenuItem se aaden (add) a los JMenu y los JMenu se aaden a la barra
principal de men (JMenuBar menuPrincipal). Finalmente se aade el JMenuBar
menuPrincipal al JFrame:
private void definirMenu() {

//// Men de Archivo
menuArchivo.setText( this.ITEM_ARCHIVO);
menuItemSalir.setText( this.ITEM_SALIR);
menuItemSalir.addActionListener(this);
menuArchivo.add(menuItemSalir);

//// Men de Ayuda
menuAyuda.setText(this.ITEM_AYUDA);
menuItemAcercaDe.setText(this.ITEM_ACERCADE);
menuItemAcercaDe.addActionListener(this);
menuAyuda.add(menuItemAcercaDe);

//// Aadimos menus al men principal y asignamos ste al applet
menuPrincipal.add(menuArchivo);
menuPrincipal.add(menuAyuda);

this.setJMenuBar(menuPrincipal); // Aadimos JMenuBar al JFrame
}

IMPORTANTE
6
Mens (III)
Antes hemos visto que la clase implementa un listener:
public class Marco extends JFrame implements ActionListener {.
Cualquier clase que implemente el listener es la que recibe los
eventos. Implementar este listener implica que se debe
implementar el mtodo actionPerformed(). Los eventos se
reciben en este mtodo:
public void actionPerformed(ActionEvent e) {
//// Opcin Acerca_de
if ( e.getActionCommand().compareTo( ITEM_ACERCADE ) == 0 )
System.out.println( "Acerca de");

//// Salir
if ( e.getActionCommand().compareTo( ITEM_SALIR ) == 0 ) {
System.out.println( "Salimos");
System.exit(0);
return;
}
}


7
Panel principal o panel raz
Toda ventana tiene un panel raz. En el siguiente ejemplo se incluyen dos
atributos: uno para el panel principal y otro para un botn:
public class Marco extends JFrame implements ActionListener {
JPanel panelPrincipal;
JButton boton;
.
Configuracin:
El panel principal se obtiene desde el propio JFrame con getContentPane()
Le indicamos al panel que la disposicin (layout) de sus componentes es del
tipo FlowLayout.
A continuacin se aade (add) el botn al panel. Sin hacer add(), el botn no
podra verse:
private void jbInit() throws Exception {
this.setTitle("Con un botn");
panelPrincipal = (JPanel) this.getContentPane();
this.setLayout( new FlowLayout());

boton = new JButton( "Un botn");
Dimension tamanioBoton = new Dimension(200,40);
boton.setPreferredSize( tamanioBoton);
panelPrincipal.add( boton );
definirMenu();
}


8
Administradores de diseo: introduccin
La norma en Swing no es colocar los componentes de acuerdo a una posicin
(x,y). Lo que se recomienda es que la posicin de los componentes
dependa del administrador de diseo (Layout Manager). El ms sencillo de
los administradores de diseo es el FlowLayout.
La ventaja de usar un administrador es que al cambiar el tamao de la ventana
los componentes se recolocan de acuerdo al administrador utilizado
Un administrador define una disposicn u orden para todo el conjunto de
elementos. Imaginemos una situacin cotidiana: si tienes que organizar un
grupo de personas en una habitacin supn que tienes dos opciones:
La primera es la ms usual, decir a cada persona la posicin exacta que debe ocupar.
La segunda opcin es ms "abstracta" y ms interesante, les digo a todos que se
organicen en funcin de un cierto orden, por ejemplo, en filas paralelas
empezando desde la izquierda, o en diagonal, etc. En la segunda opcin lo nico que
tienes que hacer es ordenar a todos los elementos que se organicen de una forma
determinada y suponemos que todos los elementos tienen la suficiente "inteligencia"
como para adoptar ese orden. Esto es algo muy semejante a lo que hacen nuestros
administradores de diseo.
Cmo se define el administrador de diseo? Por medio de la llamada a la
funcin setLayout. Esta llamada se realiza desde jbInit:
setLayout( new TIPO_DE_ADMINISTRADOR_DE_DISEO() );
9
FlowLayout
Organiza los elementos de izquierda a derecha y de arriba hacia abajo. Por
defecto la alineacin es centrada. En el siguiente ejemplo hemos puesto un
FlowLayout con una alineacin a la izquierda (LEFT):
private void jbInit() throws Exception {
JPanel panelPrincipal = (JPanel) this.getContentPane();
panelPrincipal.setLayout( new FlowLayout(FlowLayout.LEFT ) );
....
}
Las versiones del constructor de FlowLayout son:
FlowLayout( )
FlowLayout( int align ): El parmetro debe ser una constante static de la clase
FlowLayout que indica el alineamiento horizontal: FlowLayout.LEFT,
FlowLayout.RIGHT o FlowLayout.CENTER. .
FlowLayout( int align, int hgap, int vgap ): el segundo y tercer parmetro
indican la separacin horizontal y vertical en pxeles.
En el siguiente ejemplo hemos usado:
setLayout( new FlowLayout( FlowLayout.LEFT, 20, 10 ) ):
10
BorderLayout (I)
Este administrador organiza los elementos por zonas: Norte, Sur,
Este, Oeste y Centro. Veamos el siguiente ejemplo, en el que la
zona se indica en el segundo argumento de la llamada a a add():
private void jbInit() throws Exception {
JPanel panelPrincipal = (JPanel) this.getContentPane();

panelPrincipal.setLayout( new BorderLayout( ) );

panelPrincipal.add(b_juan, BorderLayout.NORTH);
panelPrincipal.add(b_pedro, BorderLayout.CENTER);
panelPrincipal.add(b_pablo, BorderLayout.SOUTH);
panelPrincipal.add(b_santiago, BorderLayout.EAST);
panelPrincipal.add(b_mateo, BorderLayout.WEST);
}
El aspecto final es:
11
BorderLayout (II)
Observe dos caractersticas importantes: cada elemento (en este
caso botones) se expande sobre la zona asignada. Adems
el ltimo elemento de una zona oculta a los anteriores
elementos de esa zona. Para entender esto, supongamos que
incluimos un botn, denominado b_judas, y lo aadimos a la
misma zona (NORTH) que b_juan:
private void jbInit() throws Exception {
....
panelPrincipal.add(b_juan, BorderLayout.NORTH);
panelPrincipal.add(b_judas, BorderLayout.NORTH);
....
}
Cul es el botn que se observa?Cul se oculta?
Las versiones del constructor de BorderLayout son:
BorderLayout( )
BorderLayout( int hgap, int vgap ): para indicar la separacin
horizontal y vertical en pxeles.

12
GridLayout
La disposicin o aspecto que indica este administrador de diseo es la
tpica un eje cartesiano, como una hoja de clculo estructurada en filas y
columnas. Proseguimos con nuestro ejemplo de los botones aplicando este
nuevo administrador:
Para usar GridLayout debe especificar las filas y columnas a la hora de
construirlo. Los elementos se aaden al applet con el orden izquierda-
derecha y arriba-abajo:
private void jbInit() throws Exception {

panelPrincipal.setLayout( new GridLayout( 2, 3 ) ); // Dos filas y tres columnas

panelPrincipal.add(b_juan);
panelPrincipal.add(b_pedro);
panelPrincipal.add(b_pablo);
panelPrincipal.add(b_santiago);
panelPrincipal.add(b_mateo);
}
Existe un segundo tipo de constructor que permite especificar la distancia
horizontal y vertical de los elementos:
GridLayout(int rows, int cols, int hgap, int vgap)
13
BoxLayout (I)
http://java.sun.com/docs/books/tutorial/uiswing/layout/
El constructor del BoxLayout exige dos argumentos, el primero es el contenedor al que se asigna. El segundo es la
orientacin general:
PAGE_AXIS: se ordenan los componentes de arriba hacia abajo.
LINE_AXIS: se ordenan los componentes de izquierda a derecha
Dos ideas para empezar:
Al no especificar tamao en los JTextField, estos componentes se expanden sobre el espacio disponible. Las etiquetas y el botn
tienen un tamao, que corresponde con el texto que le hemos asociado.
Lo que no cabe no se ve, el layout no lo coloca en huecos libres.
El siguiente paso ser:
Alinear el contenido de los campos de texto a la derecha (como se hace habitualmente con los nmeros). Para que no haya
confusin: se alinea el contenido del JTextField, no se alinea el JTextField respecto al contenedor raz:
txtAncho.setHorizontalAlignment( JTextField.RIGHT);
txtAlto.setHorizontalAlignment( JTextField.RIGHT);
Definir tamaos para los campos de texto, con la finalidad de que no se expandan. Para ello necesitamos de setMaximumSize(), que
limita el tamao mximo del componente. Adems tenemos setPreferredSize(), que no es estrictamente necesario ahora, pero resulta de
utilidad cuando pongamos el componente en un subpanel. Para no repetir lneas de cdigo, construimos un mtodo que haga el trabajo:
private void setTamao( JComponent comp, int x, int y ) {
Dimension tam = new Dimension( x, y );
comp.setMaximumSize( tam );
comp.setPreferredSize( tam );
}
De esta forma podemos determinar el tamao de cada campo:
setTamao( txtAncho, 80,20);
setTamao( txtAlto, 80,20);
Llevamos el botn hacia abajo. Para ello nos ayudaremos de un componente invisible que "empuja" a los componentes
adyacentes. En una orientacin LINE_AXIS el componente Box.createHorizontalGlue() empuja a los componentes anterior y posterior
(de acuerdo al orden de llamadas a add()) hacia los lados. En nuestro caso tenemos una orientacin PAGE_AXIS, por lo que usaremos
un Box.createVerticalGlue() entre el ltimo campo de texto y el botn, de esta forma empujamos el botn hacia abajo:
panelPrincipal.add( txtAlto );
panelPrincipal.add( Box.createVerticalGlue());
panelPrincipal.add( btnBoton1 );
14
BoxLayout (II)
Inicio.java:
public class Inicio {
/***************************************************************************
* Construye la aplicacin. Ejemplo de BoxLayout
***************************************************************************/
public static void main(String[] args) {
try {
//// Creamos JFrame con estilo y operacin de cierre
Marco frame = new Marco();
javax.swing.JFrame.setDefaultLookAndFeelDecorated(true);
frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}
catch(Exception e) {
e.printStackTrace();
}
}
}

15
BoxLayout (III)
Marco.java (I):
public class Marco extends JFrame {

JPanel panelPrincipal;

JLabel etiAncho = new JLabel( "Ancho:" );
JTextField txtAncho = new JTextField();
JLabel etiAlto = new JLabel( "Alto:" );
JTextField txtAlto = new JTextField();
JButton btnBoton1 = new JButton( "Botn 1" );

public Marco() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}


private void setTamanio( JComponent comp, int x, int y ) {
Dimension tam = new Dimension( x, y );
comp.setMaximumSize( tam );
comp.setPreferredSize( tam );
}



16
BoxLayout (IV)
Marco.java (II):
private void jbInit() throws Exception {
this.setTitle("Ejemplo de BoxLayout");
//// Centra la ventana
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = new Dimension( screenSize.width/2, screenSize.height/2 );
setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
setSize(frameSize.width, frameSize.height);

//// Configura panel principal
panelPrincipal = (JPanel) this.getContentPane();
panelPrincipal.setLayout( new BoxLayout( panelPrincipal, BoxLayout.PAGE_AXIS));
panelPrincipal.setAlignmentX( Component.LEFT_ALIGNMENT);
panelPrincipal.setBackground( Color.cyan);

//// Configuro etiquetas
setTamanio( etiAncho, 100, 20 );
etiAncho.setHorizontalAlignment(SwingConstants.LEFT);
setTamanio( etiAlto, 100, 20 );
etiAlto.setHorizontalAlignment(SwingConstants.LEFT);

//// Configuro campos de texto
txtAncho.setText( String.valueOf( this.getWidth()));
txtAncho.setBackground( Color.GREEN);
txtAncho.setHorizontalAlignment( JTextField.RIGHT );
setTamanio( txtAncho, 100, 20 );
txtAlto.setText( String.valueOf( this.getHeight()));
txtAlto.setBackground( Color.GREEN);
txtAlto.setHorizontalAlignment( JTextField.RIGHT );
setTamanio( txtAlto, 100, 20 );

//// Aado componentes y botn al panel raiz
panelPrincipal.add( etiAncho );
panelPrincipal.add( txtAncho );
panelPrincipal.add( etiAlto );
panelPrincipal.add( txtAlto );
panelPrincipal.add( Box.createVerticalGlue());
panelPrincipal.add( btnBoton1 );
}
17
Anidando paneles
En el siguiente ejemplo se puede ver que cada etiqueta y su correspondiente campo de texto lo
incluimos en un subpanel:
//// Aado etiquetas y campos a subpaneles
JPanel pnlAncho = new JPanel(); // Subpanel del ancho
pnlAncho.setLayout( new FlowLayout(FlowLayout.LEFT));
pnlAncho.setBackground( Color.BLUE);
pnlAncho.add( etiAncho );
pnlAncho.add( txtAncho );
setTamanio( pnlAncho, frameSize.width, 30 );
JPanel pnlAlto = new JPanel(); // Subpanel de la altura
pnlAlto.setLayout( new FlowLayout(FlowLayout.LEFT));
pnlAlto.setBackground( Color.RED);
pnlAlto.add( etiAlto );
pnlAlto.add( txtAlto );
setTamanio( pnlAlto, frameSize.width, 30 );

btnBoton1.setAlignmentX( Component.CENTER_ALIGNMENT );

//// Aado al panel raiz
panelPrincipal.add( pnlAncho );
panelPrincipal.add( pnlAlto );
panelPrincipal.add( Box.createVerticalGlue());
panelPrincipal.add( btnBoton1 );
panelPrincipal.add( Box.createRigidArea( new Dimension(5,5)));

Вам также может понравиться