Unidad 10: "AWT, Swing y Gráficos"
Objetivos de la Unidad:
Están disponibles en Sun cursos on-line de AWT, Swing y JavaBeans en http://developer.java.sun.com/developer/onlineTraining/
JBuilder es una herramienta de desarrollo visual que genera código fuente Java. Este tipo de herramientas pueden suponer un importante ahorro de tiempo respecto a la escritura del código a mano. JBuilder incluye una serie de manuales que están disponibles on-line tanto en formato HTML como en formato PDF en http://www.inprise.com/techpubs/jbuilder/jbuilder3. El manual Quick Start, en particular el capítulo Tutorial: Building your first application with JBuilder es un excelente guía paso a paso de cómo desarrollar una aplicación visual con JBuilder.
A parte de la gran referencia
que es el tutorial de Sun (http://java.sun.com/docs/books/tutorial) es interesante el tutorial de Swing de http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/ de la John Hopkins
University.
Como libro de texto introductorio se recomienda la obra de
Bruce Eckel "Thinking in Java" capítulo 13 (ver la Unidad 2 en el punto 2.1 de Referencias
bibliográficas)
AWT y
Swing
Una muy buena referencia de Swing si conoce AWT se puede
consultar en http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-Intro.html
AWT: Abstract Window Toolkit.
Consiste en una librería de clases que utiliza el sistema de ventanas nativo del sistema donde se ejecuta. Su diseño se basó en una estrategia de "común denominador" al incorporar las características comunes de varios sistemas de ventanas tras un proceso de abstracción. Una aplicación AWT se compila y ejecuta sobre cualquier plataforma pero el "look" dependerá de las mismas. Tendremos aspectos tipo Windows, tipo Motif, tipo Mac, tipo OS/2.
Ventajas:
Inconvenientes:
Swing:
Consiste en la extensión de la librería AWT a unos componentes gestionados íntegramente por Java. El "look" es propio de Java y se igual en cualquier plataforma. La clase Button de AWT es la clase base de JButton de Swing. Igual para Frame y JFrame, Applet y JApplet, TextField y JTextField, etc.
Ventajas:
Inconvenientes:
Los componentes AWT y Swing
desde el punto de vista de compatibilidad Java podrían mezclarse, pero ello es
muy poco recomendable. Los sistemas de pintado y gestión de eventos son
distintos y ello suele dar problemas de repintado de los componentes.
Swing y
AWT forma parte de las JFC (Java Foundation Classes) que corresponden a una
visión conjunrta.
Un sistema interesante de
experimentar con herramientas como JBuilder ya que visualmente nos permite
añadir y parametrizar componentes visuales (al estilo Visual Basic) de modo que
a medida que se va trabajando visualmente también se se va generando el código
Java.
En el caso concreto de JBuilder todo el código generado se ubica en el
método jbInit() que es llamado por el constructor del formulario o por el método
init() del applet (según proceda). El código generado es muy al estilo tutorial
por lo que se puede analizar y probar a medida que se trabaja
visualmente.
2.- Gestión de eventos
1.1. Comparación con JDK 1.02
/* Ejemplo 1.02 */
import java.awt.*;
public class ButtonActionsTest extends java.applet.Applet {
Button redButton,blueButton,greenButton,whiteButton,blackButton;
public void init() {
setBackground(Color.white);
setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));redButton = new Button("Red");
add(redButton);
blueButton = new Button("Blue");
add(blueButton);
greenButton = new Button("Green");
add(greenButton);
whiteButton = new Button("White");
add(whiteButton);
blackButton = new Button("Black");
add(blackButton);
}public boolean action(Event evt, Object arg) {
if (evt.target instanceof Button) {
changeColor((Button)evt.target);
return true;
} else return false;
}void changeColor(Button b) {
if (b == redButton) setBackground(Color.red);
else if (b == blueButton) setBackground(Color.blue);
else if (b == greenButton) setBackground(Color.green);
else if (b == whiteButton) setBackground(Color.white);
else setBackground(Color.black);repaint();
}
}<HTML>
<HEAD>
<TITLE>Button Actions</TITLE>
</HEAD>
<BODY>
<H2>Chapter Twelve: Button Actions</H2>
<P>
<APPLET CODE="ButtonActionsTest.class" WIDTH=250 HEIGHT=150>
</APPLET>
<P>
<A HREF="ButtonActionsTest.java">The Source</A>
</BODY>
</HTML>
Mismo ejemplo que el anterior pero con
gestión de eventos JDK1.1
/* button actions */
import java.awt.*;
public class ButtonActionsTest extends java.applet.Applet {
Button redButton,blueButton,greenButton,whiteButton,blackButton;
public void init() {
setBackground(Color.white);
setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));redButton = new Button("Red");
add(redButton);
blueButton = new Button("Blue");
add(blueButton);
greenButton = new Button("Green");
add(greenButton);
whiteButton = new Button("White");
add(whiteButton);
blackButton = new Button("Black");
add(blackButton);
}public boolean action(Event evt, Object arg) {
if (evt.target instanceof Button) {
changeColor((Button)evt.target);
return true;
} else return false;
}void changeColor(Button b) {
if (b == redButton) setBackground(Color.red);
else if (b == blueButton) setBackground(Color.blue);
else if (b == greenButton) setBackground(Color.green);
else if (b == whiteButton) setBackground(Color.white);
else setBackground(Color.black);repaint();
}
}<HTML>
<HEAD>
<TITLE>Button Actions</TITLE>
</HEAD>
<BODY>
<H2>Chapter Twelve: Button Actions</H2>
<P>
<APPLET CODE="ButtonActionsTest.class" WIDTH=250 HEIGHT=150>
</APPLET>
<P>
<A HREF="ButtonActionsTest.java">The Source</A>
</BODY>
</HTML>
3.- Gráficos
import java.awt.*;
public class Lamp extends java.applet.Applet {
public void paint(Graphics g) {
// the lamp platform
g.fillRect(0,250,290,290);// the base of the lamp
g.drawLine(125,250,125,160);
g.drawLine(175,250,175,160);// the lamp shade, top and bottom edges
g.drawArc(85,157,130,50,-65,312);
g.drawArc(85,87,130,50,62,58);// lamp shade, sides
g.drawLine(85,177,119,89);
g.drawLine(215,177,181,89);// dots on the shade
g.fillArc(78,120,40,40,63,-174);
g.fillOval(120,96,40,40);
g.fillArc(173,100,40,40,110,180);
}
}
<HTML>
<HEAD>
<TITLE>A Lamp (or a mushroom)</TITLE>
</HEAD>
<BODY>
<H2>Chapter Nine: A Lamp (or a mushroom)</H2>
<P>
<APPLET CODE="Lamp.class" WIDTH=300 HEIGHT=300>
If you were running Java, you would see a lamp here.
</APPLET>
<P>
<A HREF="Lamp.java">The Source</A>
</BODY>
</HTML>
4.- Textos y fuentes
import java.awt.Font;
import java.awt.Graphics;public class ManyFonts extends java.applet.Applet {
public void paint(Graphics g) {
Font f = new Font("TimesRoman", Font.PLAIN, 18);
Font fb = new Font("TimesRoman", Font.BOLD, 18);
Font fi = new Font("TimesRoman", Font.ITALIC, 18);
Font fbi = new Font("TimesRoman", Font.BOLD + Font.ITALIC, 18);g.setFont(f);
g.drawString("This is a plain font", 10, 25);
g.setFont(fb);
g.drawString("This is a bold font", 10, 50);
g.setFont(fi);
g.drawString("This is an italic font", 10, 75);
g.setFont(fbi);
g.drawString("This is a bold italic font", 10, 100);
}}
<HTML>
<HEAD>
<TITLE>Many Fonts</TITLE>
</HEAD>
<BODY BGCOLOR="white">
<H2>Chapter Nine: Many Fonts</H2>
<P>Print lots of fonts in a Java applet:
<BR><APPLET CODE="ManyFonts.class" WIDTH=250 HEIGHT=150>
</APPLET>
<P>
<A HREF="ManyFonts.java">The Source</A>
</BODY>
</HTML>
Para añadir nuevos fuentes a Java consultar en http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
5.- Layout
managers
/* flowlayout test */
import java.awt.*;
public class FlowLayoutTest extends java.applet.Applet {
public void init() {
setLayout(new FlowLayout());
add(new Button("One"));
add(new Button("Two"));
add(new Button("Three"));
add(new Button("Four"));
add(new Button("Five"));
add(new Button("Six"));
}
}
/* border layouts */
import java.awt.*;
public class BorderLayoutTest extends java.applet.Applet {
public void init() {
setLayout(new BorderLayout());
add("North", new Button("One"));
add("East", new Button("Two"));
add("South", new Button("Three"));
add("West", new Button("Four"));
add("Center", new Button("Five"));
}
}/* grid layouts */
import java.awt.*;
public class GridLayoutTest extends java.applet.Applet {
public void init() {
setLayout(new GridLayout(3,2));
add(new Button("One"));
add(new Button("Two"));
add(new Button("Three"));
add(new Button("Four"));
add(new Button("Five"));
add(new Button("Six"));
}
}
/* grid bag layouts */
import java.awt.*;
public class GridBagTestFinal extends java.applet.Applet
{void buildConstraints(GridBagConstraints gbc, int gx, int gy,
int gw, int gh,
int wx, int wy) {
gbc.gridx = gx;
gbc.gridy = gy;
gbc.gridwidth = gw;
gbc.gridheight = gh;
gbc.weightx = wx;
gbc.weighty = wy;
}public void init()
{
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
setLayout(gridbag);// Name label
buildConstraints(constraints, 0, 0, 1, 1, 10, 40);
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.EAST;
Label label1 = new Label("Name:", Label.LEFT);
gridbag.setConstraints(label1, constraints);
add(label1);// Name text field
buildConstraints(constraints, 1, 0, 1, 1, 90, 0);
constraints.fill = GridBagConstraints.HORIZONTAL;
TextField tfname = new TextField();
gridbag.setConstraints(tfname, constraints);
add(tfname);// password label
buildConstraints(constraints, 0, 1, 1, 1, 0, 40);
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.EAST;
Label label2 = new Label("Password:", Label.LEFT);
gridbag.setConstraints(label2, constraints);
add(label2);// password text field
buildConstraints(constraints, 1, 1, 1, 1, 0, 0);
constraints.fill = GridBagConstraints.HORIZONTAL;
TextField tfpass = new TextField();
tfpass.setEchoCharacter('*');
gridbag.setConstraints(tfpass, constraints);
add(tfpass);// OK Button
buildConstraints(constraints, 0, 2, 2, 1, 0, 20);
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.CENTER;
Button okb = new Button("OK");
gridbag.setConstraints(okb, constraints);
add(okb);}
}
Para ejecutar estos
applets se debe adaptar el parámetro code del tag applet el
siguiente código HTML:
<html>
<head>
<title>Ejemplo de
la Unidad 10</title>
</head>
<body>
<applet
code=GridBagTestFinal.class width=400
height=250></applet>
</body>
</html>
jview /a applet.html
5.1 Ejemplos
comparativos AWT-Swing
// Ventana.java
import java.awt.*; import java.awt.event.*;
public class Ventana extends Frame implements ActionListener, WindowListener
{
Label lab;
TextArea ta;
Panel pan;
Button ok, cancel; public Ventana()
{
setLayout(new BorderLayout());
lab = new Label("Ejemplo de los patrones Composite y Observer");
add("North", lab); ta = new TextArea();
add("Center", ta); ok = new Button("Ok");
cancel = new Button("Cancel");
pan = new Panel();
pan.setLayout(new FlowLayout());
pan.add(ok);
pan.add(cancel);
add("South", pan);ok.addActionListener(this); addWindowListener(this); }
public void actionPerformed(ActionEvent e)
{
ta.append("abcde ");
} public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {} public void windowClosing(WindowEvent e)
{
System.exit(0);
} public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public static void main(String[] args)
{
Ventana v = new Ventana();
v.setSize(400, 300);
v.setVisible(true);
}
}
Al ejecutarlo se obtiene:
// JVentana.java
import java.awt.*; import javax.swing.*; import java.awt.event.*;
public class JVentana extends JFrame implements ActionListener, WindowListener
{
JLabel lab;
JTextArea ta;
JPanel pan;
JButton ok, cancel; public JVentana()
{
getContentPane().setLayout(new BorderLayout());
lab = new JLabel("Ejemplo de los patrones Composite y Observer");
getContentPane().add("North", lab); ta = new JTextArea();
getContentPane().add("Center", ta); ok = new JButton("Ok");
cancel = new JButton("Cancel");
pan = new JPanel();
pan.setLayout(new FlowLayout());
pan.add(ok);
pan.add(cancel);
getContentPane().add("South", pan);ok.addActionListener(this); addWindowListener(this); }
public void actionPerformed(ActionEvent e)
{
ta.append("abcde ");
} public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {} public void windowClosing(WindowEvent e)
{
System.exit(0);
} public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public static void main(String[] args)
{
JVentana v = new JVentana();
v.setSize(400, 300);
v.setVisible(true);
}
}
Al ejecutarlo se obtiene:
6.- Double
buffering
/* Animación sin double buffering */
import java.awt.Graphics;
import java.awt.Color;public class Checkers extends java.applet.Applet implements Runnable {
Thread runner;
int xpos;public void start() {
if (runner == null); {
runner = new Thread(this);
runner.start();
}
}public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}public void run() {
while (true) {
for (xpos = 5; xpos < = 105; xpos+=4) {
repaint();
try { Thread.sleep(100); }
catch (InterruptedException e) { }
}
xpos=5;
}
}public void update(Graphics g) {
paint(g);
}public void paint(Graphics g) {
// fondo
g.setColor(Color.black);
g.fillRect(0,0,100,100);
g.setColor(Color.white);
g.fillRect(100,0,100,100);g.setColor(Color.red);
g.fillOval(xpos,5,90,90);
}
}
/* Animación con double buffering */
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;public class Checkers2 extends java.applet.Applet implements Runnable {
Thread runner;
int xpos;
Image offscreenImg;
Graphics offscreenG;public void init() {
offscreenImg = createImage(this.size().width, this.size().height);
offscreenG = offscreenImg.getGraphics();
}public void start() {
if (runner == null); {
runner = new Thread(this);
runner.start();
}
}public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}public void run() {
while (true) {
for (xpos = 5; xpos < = 105; xpos+=4) {
repaint();
try { Thread.sleep(100); }
catch (InterruptedException e) { }
}
xpos = 5;
}
}public void update(Graphics g) {
paint(g);
}public void paint(Graphics g) {
// fondo
offscreenG.setColor(Color.black);
offscreenG.fillRect(0,0,100,100);
offscreenG.setColor(Color.white);
offscreenG.fillRect(100,0,100,100);offscreenG.setColor(Color.red);
offscreenG.fillOval(xpos,5,90,90);g.drawImage(offscreenImg,0,0,this);
}public void destroy() {
offscreenG.dispose();
}
}
7.- Impresión
El JDK 1.1 ofrece servicios de
impresión. Pueden encontrarse detalles de qué y cómo en http://developer.java.sun.com/developer/TechTips/1997/tt0924.html. Java 2 introduce un nuevo modelo de
impresión del que hay detalles en http://developer.java.sun.com/developer/technicalArticles/Printing/index.html
Unidad anterior - Unidad siguiente
Copyright DENVIR STUDIOS ®
Lima - Perú, 2002