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>

Si se denomina applet.html a este fichero HTML, para probar el ejemplo puede utilizarse un navegador o un visor de applets.
El visor del JDK es appletviewer y se invoca:

appletviewer applet.html

El visor de Microsoft se invoca:

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

Hosted by www.Geocities.ws

1