Programación de Gráficos

Curso Java Experto

Clase I

AWT

Delega creación y comportamiento al juego de herramientas IGU nativo de cada plataforma blanco (Windows, Macintosh, etc)

SWING

Elementos de interfaz de usuario (botonos, menús, etc) se pintaban sobre una venta en blanco.

Abstract Window Toolkit

Java 1.2

Java 1.0

WRITE ONCE, RUN EVERYWHERE

Swing dancing!

Ventajas de Swing

  • Elementos de interfaz de usuario rico y cómodo.
  • Poca dependencia de la plataforma subyacente -> menos proclive a tener defectos específicos de una u otra plataforma.
  • Experiencia de usuario coherente

Desventaja de Swing

  • Si los elementos de la IGU tienen el mismo aspecto en todas las plataformas, entonces van a tener un aspecto distinto que los controles nativos y los usuario estarán menos familiarizados con ellos.

 

Solución: programar un nuevo look and feel con Synth. 

Look and Feel predeterminado Metal con theme Ocean.

Creación de un marco

Marco: JFRAME

Ventanas de nivel superior (las que no están dentro de otra ventana).

 

No se pintan, los adornos (botones, barra de título, iconos y demás) van a ser dibujados por el sistema de ventanas de usuario.

Paquete java.awt

Paquete javax.swing

Frame

JFrame

Características de JFrame

  • Tamaño inútil de 0x0 píxeles: setSize(x,y)
  • Nacen invisibles: setVisible(boolean)
  • Se le debe decir que deben hacer cuando se cierren: setDefaultCloseOperation(numero)

 

Ver http://docs.oracle.com/javase/8/docs/api/

Ejemplo 1

import javax.swing.JFrame;

public class PruebaMarcoSencillo {

	public static void main(String[] args) {
		MarcoSencillo marco = new MarcoSencillo();
		marco.setVisible(true);
		marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

}

class MarcoSencillo extends JFrame {
	
	public MarcoSencillo (){
		setSize(500,300);		
	}
	
}

Object

Component

Container

Window

Frame

JFrame

setLocation(x,y)

setBounds(x,y,ancho,largo)

setIconImage(Image image)

setTitle(String title)

setResizable(Boolean resizable)

dispose()

Ejemplo 2

import javax.swing.JFrame;

public class PruebaMarcoSencillo {

	public static void main(String[] args) {
		MarcoSencillo marco = new MarcoSencillo();
		marco.setVisible(true);
		marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

}

class MarcoSencillo extends JFrame {
	
	public MarcoSencillo (){
		setSize(500,300);
		setLocation(300,200);
		setResizable(true);
		setTitle("Mi ventana");
	}
	
}

Clase Toolkit

Almacén de métodos que se comunican con el sistema nativo de ventanas.

Toolkit

getDefaultToolkit()

getScreenSize()

Ejemplo 3

  • Marco cuya área es la cuarta parte del total de la pantalla.
  • Está centrado en medio de la pantalla
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.JFrame;

public class PruebaMarcoCentrado {

	public static void main(String[] args) {
		MarcoCentrado marco = new MarcoCentrado();
		marco.setVisible(true);
		marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

}

class MarcoCentrado extends JFrame {

	public MarcoCentrado() {
		Toolkit mipantalla = Toolkit.getDefaultToolkit();
		Dimension tamano = mipantalla.getScreenSize();
		int ancho = tamano.width;
		int altura = tamano.height;

		setSize(ancho / 2, altura / 2);
		setLocation(ancho / 4, altura / 4);

		Image icono = mipantalla.getImage("src/img/images.jpg");
		setIconImage(icono);
	}

}

Visualización de información en una lamina

Estructura JFrame

Object

Component

Container

JComponent

JPanel

La clase JPanel es la encargada de construir laminas donde poder dibujar y escribir. Debemos crear una clase que herede de JPanel.

paintComponent(Graphics g)

Características

  • Tienen una superficie sobre la que se puede dibujar.
  • Son, a su vez contenedores.
  • Para dibujar sobre una lamina:
    • se define una clase que extiende de JPanel
    • se invalida el método paintComponent de esa clase
  • No se debe llamar directamente al método paintComponent.
  • Utilizar método super() en el método paintComponent.

Ejemplo 4

import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class PruebaLamina {

	public static void main(String[] args) {
		Marco marco = new Marco();
		marco.setVisible(true);
		marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}
}

class Marco extends JFrame {

	public Marco() {
		setSize(500, 300);
		setLocation(300, 200);
		setResizable(true);
		setTitle("Dibujando un texto");
		Lamina lamina = new Lamina();
		add(lamina);
	}

}

class Lamina extends JPanel {

	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		g.drawString("Texto sobre lamina", 100, 50);
	}
}

Trabajando con formas 2D

Graphics

Poseía métodos para dibujar rectángulos, elipses y demás.

Operaciones de trazado muy limitadas. No se podían variar los trazos ni rotar.

Java 1.0.

Graphics2D

Implementa un potente conjunto de operaciones gráficas.

Ejercicio 5: Graphics

import javax.swing.JFrame;
import javax.swing.JPanel;

public class PruebaGraphics {

	public static void main(String[] args) {
		MarcoFiguras marco = new MarcoFiguras();
		marco.setVisible(true);
		marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}
}
	
	class MarcoFiguras extends JFrame{
		public MarcoFiguras(){
			setSize(300,300);
			setTitle("Prueba Figuras");
			LaminaConFiguras lamina = new LaminaConFiguras();
			add(lamina);
		}
	}
	
	class LaminaConFiguras extends JPanel{
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.drawRect(100, 100, 100, 100);
			g.drawLine(100, 50, 200, 200);
		}
	}

Para dibujar formas en la biblioteca Java 2D, es necesario obtener un objeto de la clase Graphics2D:

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
...
}

La bibliteca de clases Java2D organiza las formas geometricas de una manera orientada a objetos.

  • Line2D
  • Rectangle2D
  • Ellipse2D
Rectangle2D rectangulo = new Rectangle2D.Double(xizq, ysup, anchura, altura);
g2.draw(rectangulo);
float f = 1.2; //Error
float f = 1.2F; //Ok

Rectangle2D r = ...;
float f = r.getWidth(); //Error

float f = (float) r.getWidth(); //Ok

Los cálculos hechos en float son más rápidos y los valores float ocupan menos memoria.

Rectangle2D.Double rectangulo = new Rectangle2D.Double(10.0F, 25.0F, 22.5F, 20.0F);
Rectangle2D.Float rectangulo = new Rectangle2D.Float(10.0, 25.0, 22.5, 20.0);
Rectangle2D rectangulo = new Rectangle2D.Double(10.0F, 25.0F, 22.5F, 20.0F);
Rectangle2D rectangulo = new Rectangle2D.Float(10.0, 25.0, 22.5, 20.0);

En realidad, dado que tanto Rectangle2D.Float como Rectangle2D.Double extiende de la clase Rectangle2D y los métodos de la subclases se limitan a invalidar métodos de la superclase Rectangle2D, no resulta beneficioso recordar el tipo exacto.

Lo que se acaba de indicar para Rectangle2D sigue siendo válido para el resto de las formas.

Point2D p = new Point2D.Double(10,20);

Puntos

Rectángulo

Rectangle2D rectangulo = new Rectangle2D.Double(xizq, ysup, anchura, altura);
Rectangle2D rectangulo = new Rectangle2D.Double();
rectangulo.setFrameFromDiagonal(px,py,qx,qy);

Elipse

Ellipse2D elipse = new Ellipse2D.Double();
elipse.setFrame(rectangulo);
Ellipse2D rectangulo = new Ellipse2D.Double(xizq, ysup, anchura, altura);

Línea

Line2D linea = new Line2D(principio,fin);

Jerarquía Clases

Ejercicio 6

class LaminaConFiguras extends JPanel {
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;

		// Dibujar rectangulo
		double xizq = 100;
		double ysup = 100;
		double anchura = 200;
		double altura = 150;

		Rectangle2D rectangulo = new Rectangle2D.Double(xizq, ysup, anchura, altura);
		g2.draw(rectangulo);

		// Dibujar elipse inscrita
		Ellipse2D elipse = new Ellipse2D.Double();
		elipse.setFrame(rectangulo);
		g2.draw(elipse);

		// dibujar linea diagonal
		g2.draw(new Line2D.Double(xizq, ysup, xizq + anchura, ysup + altura));

		// dibujar un circulo con el mismo centro
		double xcentro = rectangulo.getCenterX();
		double ycentro = rectangulo.getCenterY();
		double radio = 150;

		Ellipse2D circulo = new Ellipse2D.Double();
		circulo.setFrameFromCenter(xcentro, ycentro, xcentro + radio, ycentro + radio);
		g2.draw(circulo);
	}
}

Ejercicicios

  1. Crear un Marco sencillo  utilizando setSize,setVisible y setDefaultCloseOperation.
  2. Crear un Marco utilizando setSize, setLocation, setResizable,setBounds,setTitle.
  3. Crear un marco que cumpla las siguientes condiciones:
    • Marco cuya área es la cuarta parte del total de la pantalla.
    • Está centrado en medio de la pantalla
    • Icono personalizado
  4. Crear un marco con una lámina que contenga un texto definido.
  5. Crear un marco con una lámina que contenga una línea y un rectángulo utilizando la clase Graphics.
  6. Dibuja en una lámina: un rectángulo, una elipse inscrita en el rectángulo, una diagonal del rectángulo y un círculo que tiene como centro el rectángulo.
Made with Slides.com