Está en la página 1de 149

LA BIBLIA DE JAVA = http://es.slideshare.

net/jeanHisoka/labibliadejava2
MANUAL DE JAVA 320 PAGS. http://www.jorgesanchez.net/programacion/manuales/Java.pdf
http://pedrobeltrancanessabiblioteca.weebly.com/uploads/1/2/4/0/12405072/java_swing.pdf
transformar imagenes con java
System.out.println(Math.rint(0.891));
for (var i = 0; i < myVar.length; i+3) {
//every three
}
/ Mtodos de acceso (get)
public int getNum()
{
return num;
}
public double getSaldo()
{
return saldo;
}
public String getNombre()
{
return nombre;
}
public double devuelve() // Sin parametros
{...
return . . . ;}
public void asigna(
double x
) // Un parametro, x de tipo double
{...}
publ
ic int elMayor(int a, int b) // Dos parametros, a y b de tipo int
{...}
public static double sumatorio (
double [] v
) // Un parametro, v, array real
{...}
public boolean caducado (
F
echa fechaLimite
)
// Un parmetro
de la clase Fecha
http://ocw.upm.es/lenguajes-y-sistemas-informaticos/programacion-en-javai/Contenidos/LecturaObligatoria/15-parametrosoargumentos.pdf
http://elvex.ugr.es/decsai/java/pdf/6A-Arrays.pdf
Arreglos: DECLARACION del arreglo = private float coordenadas []; private float
coordenadas[] []; (para 2 dimensiones); CREACION: float coordenadas [] = new float [7];
(7 es el tamao del arreglo);
1

float coordenadas[] [] = new float [10][10]; (tamao 10x10)

ESTRUCTURA DE LOS METODOS: declaracin de parmetros en el


ENCABEZADO:
public double devuelve() // Sin parmetros tipo Get
{ . . .
return . . . ;}
public void asigna(double x) // Un parametro, x de tipo double
{ . . . }
(tipo Set)
public int elMayor(int a, int b) // Dos parametros, a y b de tipo
int
{ . . . }
public static double sumatorio (double [] v) // Un parametro, v,
array real
{ . . . }
public boolean caducado (Fecha fechaLimite) // Un parmetro
de la clase Fecha
USO DE LA PALABRA THIS
Tu ejemplo no est completo, le faltan las variables de la clase, debera ser algo as:
String name;
String favoriteFood;
public User(String name, String favoriteFood) {
this.name = name;
this.favoriteFood = favoriteFood;
}
Fjate que las variables del constructor se llaman exactamente igual que las de la clase,
cmo diferenciarlas?, con "this" que hace referencia a la variable de la clase (las de
hasta arriba en este caso). Por eso this.name = name asigna el valor pasado como
parmetro al constructor a la variable de clase.
Como cultura general, las variables de clase se llaman atributos.

Tutoriales de la universidad de Princeton = EXCELENTE

ttp://introcs.cs.princeton.edu/java/stdlib/Picture.java.html ;
Compilation: javac Picture.java
* Execution: java Picture imagename
*
* Data type for manipulating individual pixels of an image. The original
* image can be read from a file in jpg, gif, or png format, or the
* user can create a blank image of a given size. Includes methods for
* displaying the image in a window on the screen or saving to a file.
*
* % java Picture mandrill.jpg
*
* Remarks
* ------* - pixel (x, y) is column x and row y, where (0, 0) is upper left
*
* - see also GrayPicture.java for a grayscale version
*
*************************************************************************/
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

java.awt.Color;
java.awt.FileDialog;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.KeyEvent;
java.awt.image.BufferedImage;
java.io.File;
java.io.IOException;
java.net.URL;
javax.imageio.ImageIO;
javax.swing.ImageIcon;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.KeyStroke;

/**
* This class provides methods for manipulating individual pixels of
* an image. The original image can be read from a <tt>.jpg</tt>, <tt>.gif</tt>,
* or <tt>.png</tt> file or the user can create a blank image of a given size.
* This class includes methods for displaying the image in a window on
* the screen or saving it to a file.
* <p>
* Pixel (<em>x</em>, <em>y</em>) is column <em>x</em> and row <em>y</em>.
* By default, the origin (0, 0) is upper left, which is a common convention
* in image processing.
* The method <tt>setOriginLowerLeft()</tt> change the origin to the lower left.
* <p>
* For additional documentation, see
* <a href="http://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
* <i>Introduction to Programming in Java: An Interdisciplinary Approach</i>

* by Robert Sedgewick and Kevin Wayne.


*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class Picture implements ActionListener {
private BufferedImage image;
// the rasterized image
private JFrame frame;
// on-screen view
private String filename;
// name of file
private boolean isOriginUpperLeft = true; // location of origin
private final int width, height;
// width and height
/**
* Initializes a blank <tt>width</tt>-by-<tt>height</tt> picture, with <tt>width</tt> columns
* and <tt>height</tt> rows, where each pixel is black.
*/
public Picture(int width, int height) {
if (width < 0) throw new IllegalArgumentException("width must be nonnegative");
if (height < 0) throw new IllegalArgumentException("height must be nonnegative");
this.width = width;
this.height = height;
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// set to TYPE_INT_ARGB to support transparency
filename = width + "-by-" + height;
}
/**
* Initializes a new picture that is a deep copy of <tt>picture</tt>.
*/
public Picture(Picture picture) {
width = picture.width();
height = picture.height();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
filename = picture.filename;
for (int col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
image.setRGB(col, row, picture.get(col, row).getRGB());
}
/**
* Initializes a picture by reading in a .png, .gif, or .jpg from
* the given filename or URL name.
*/
public Picture(String filename) {
this.filename = filename;
try {
// try to read from file in working directory
File file = new File(filename);
if (file.isFile()) {
image = ImageIO.read(file);
}
// now try to read from file in same directory as this .class file
else {
URL url = getClass().getResource(filename);
if (url == null) { url = new URL(filename); }
image = ImageIO.read(url);

}
width = image.getWidth(null);
height = image.getHeight(null);

}
catch (IOException e) {
// e.printStackTrace();
throw new RuntimeException("Could not open file: " + filename);
}

/**
* Initializes a picture by reading in a .png, .gif, or .jpg from a File.
*/
public Picture(File file) {
try { image = ImageIO.read(file); }
catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not open file: " + file);
}
if (image == null) {
throw new RuntimeException("Invalid image file: " + file);
}
width = image.getWidth(null);
height = image.getHeight(null);
filename = file.getName();
}
/**
* Returns a JLabel containing this picture, for embedding in a JPanel,
* JFrame or other GUI widget.
* @return the <tt>JLabel</tt>
*/
public JLabel getJLabel() {
if (image == null) { return null; }
// no image available
ImageIcon icon = new ImageIcon(image);
return new JLabel(icon);
}
/**
* Sets the origin to be the upper left pixel. This is the default.
*/
public void setOriginUpperLeft() {
isOriginUpperLeft = true;
}
/**
* Sets the origin to be the lower left pixel.
*/
public void setOriginLowerLeft() {
isOriginUpperLeft = false;
}
/**
* Displays the picture in a window on the screen.
*/
public void show() {

// create the GUI for viewing the image if needed


if (frame == null) {
frame = new JFrame();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem menuItem1 = new JMenuItem(" Save... ");
menuItem1.addActionListener(this);
menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
menu.add(menuItem1);
frame.setJMenuBar(menuBar);

frame.setContentPane(getJLabel());
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setTitle(filename);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
// draw
frame.repaint();
}
/**
* Returns the height of the picture.
* @return the height of the picture (in pixels)
*/
public int height() {
return height;
}
/**
* Returns the width of the picture.
* @return the width of the picture (in pixels)
*/
public int width() {
return width;
}
/**
* Returns the color of pixel (<tt>col</tt>, <tt>row</tt>).
* @return the color of pixel (<tt>col</tt>, <tt>row</tt>)
* @throws IndexOutOfBoundsException unless both 0 &le; <tt>col</tt> &lt; <tt>width</tt>
* and 0 &le; <tt>row</tt> &lt; <tt>height</tt>
*/
public Color get(int col, int row) {
if (col < 0 || col >= width()) throw new IndexOutOfBoundsException("col must be between 0
and " + (width()-1));
if (row < 0 || row >= height()) throw new IndexOutOfBoundsException("row must be between
0 and " + (height()-1));
if (isOriginUpperLeft) return new Color(image.getRGB(col, row));

else

return new Color(image.getRGB(col, height - row - 1));

}
/**
* Sets the color of pixel (<tt>col</tt>, <tt>row</tt>) to given color.
* @throws IndexOutOfBoundsException unless both 0 &le; <tt>col</tt> &lt; <tt>width</tt>
* and 0 &le; <tt>row</tt> &lt; <tt>height</tt>
* @throws NullPointerException if <tt>color</tt> is <tt>null</tt>
*/
public void set(int col, int row, Color color) {
if (col < 0 || col >= width()) throw new IndexOutOfBoundsException("col must be between 0
and " + (width()-1));
if (row < 0 || row >= height()) throw new IndexOutOfBoundsException("row must be between
0 and " + (height()-1));
if (color == null) throw new NullPointerException("can't set Color to null");
if (isOriginUpperLeft) image.setRGB(col, row, color.getRGB());
else
image.setRGB(col, height - row - 1, color.getRGB());
}
/**
* Is this Picture equal to obj?
* @return <tt>true</tt> if this picture is the same dimension as <tt>obj</tt>
* and if all pixels have the same color
*/
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
if (obj.getClass() != this.getClass()) return false;
Picture that = (Picture) obj;
if (this.width() != that.width()) return false;
if (this.height() != that.height()) return false;
for (int col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
if (!this.get(col, row).equals(that.get(col, row))) return false;
return true;
}
/**
* Saves the picture to a file in a standard image format.
* The filetype must be .png or .jpg.
*/
public void save(String name) {
save(new File(name));
}
/**
* Saves the picture to a file in a standard image format.
*/
public void save(File file) {
this.filename = file.getName();
if (frame != null) { frame.setTitle(filename); }
String suffix = filename.substring(filename.lastIndexOf('.') + 1);
suffix = suffix.toLowerCase();
if (suffix.equals("jpg") || suffix.equals("png")) {
try { ImageIO.write(image, suffix, file); }
catch (IOException e) { e.printStackTrace(); }

}
else {
System.out.println("Error: filename must end in .jpg or .png");
}

/**
* Opens a save dialog box when the user selects "Save As" from the menu.
*/
public void actionPerformed(ActionEvent e) {
FileDialog chooser = new FileDialog(frame,
"Use a .png or .jpg extension", FileDialog.SAVE);
chooser.setVisible(true);
if (chooser.getFile() != null) {
save(chooser.getDirectory() + File.separator + chooser.getFile());
}
}
/**
* Tests this <tt>Picture</tt> data type. Reads a picture specified by the command-line
argument,
* and shows it in a window on the screen.
*/
public static void main(String[] args) {
Picture picture = new Picture(args[0]);
System.out.printf("%d-by-%d\n", picture.width(), picture.height());
picture.show();
}
}

http://introcs.cs.princeton.edu/31datatype/

Java: abrir imagen, leer pxeles y pasar a escala de grises. Procesamiento digital de
imgenes I. http://algoimagen.blogspot.com/2013/08/java-abrir-imagen-leer-pixelesy-pasar.html
Cargar una imagen de archivo en el disco duro al JFrame de Netscape =
http://ordenador.wingwit.com/Programacion/javaprogramming/89469.html#.VGUkBGfzjSh

mtodos para transformar objetos de tipo BufferedImage, Image, ImageIcon e Icon


entre ellos. (funcion) = http://algoimagen.blogspot.com/2013/09/java-convertirobjetos.html

Dibujo de Polgonos
http://jugandoconjava.co/tutoriales/jFrames/dibujandoJFrame/dibujandoJFrame.html
Curso programacin java = http://recursosformacion.com/wordpress/2013/05/javapara-programadores-5-3los-metodos-graphics-y-paint/
Trabajar con varios JFrame = https://www.youtube.com/watch?v=Ha6YBbK65XI

// Para leer un pixel determinado(x,y) de la imagen


int color = image.getRGB(x,y);
// o para escribir el pixel en lugar determinado, asignndole el color
8

image.setRGB(x,y,color);

A continuacin vamos a crear un filtro que convierta una imagen en color a escala
de grises. Para obtener la escala de grises debemos obtener de cada punto una
tonalidad idntica para asociarla a los tres colores primarios. En nuestro caso para
obtener valor nico vamos a realizar la media de las tres tonalidades de la imagen
origen. Aqu tenis el algoritmo.
En el anterior algoritmo crea una imagen de las mismas dimensiones que la imagen
original. A continuacin recorre las imgenes y obtiene la media de tonos de cada
punto almacenando esta media en todos los tonos de la segunda imagen.
http://www.genbetadev.com/java-j2ee/tratamiento-de-imagenes-i-escala-de-grises

http://www.aprenderaprogramar.com/foros/index.php?topic=1514.0
APRENDER A PROGRAMAR

FORO

http://aprenderaprogramar.com/index.php?
option=com_content&view=category&id=68&Itemid=188
http://es.wikihow.com/llamar-a-un-m%C3%A9todo-en-Java

tratamiento imgenes en JScroll Pane


http://atobeto-eremita.blogspot.com/search/label/Procesamiento%20de%20im
%C3%A1genes
http://atobeto-eremita.blogspot.com/2009/09/tratamiento-de-imagenes-en-java-parte1.html
http://programacion.net/articulo/swing_y_jfc_java_foundation_classes_94/21
Este programa establece el cliente cuando crea el panel desplazable.
// where the member variables are declared
private ScrollablePicture picture;
...
// where the GUI is created
picture = new ScrollablePicture( ... );
JScrollPane pictureScrollPane = new JScrollPane(picture);
Se puede cambiar dinmicamente el cliente del panel desplazable llamado al mtodo
setViewportView.
ScrollablePicture implementa el interface Scrollable principalmente para afectar a los
incrementos de unidad y de bloque.
Configurar el ScrollPane
Mtodo
Propsito
JScrollPane()
JScrollPane(Component)
JScrollPane(int, int)
JScrollPane(Component, int, int)
9

DE

Crea un ScrollPanel El parmetro Component, cuando existe, selecciona el cliente.


Los dos parmetros int, cuando existen, seleccionan los vigilantes de seguridad de las
barras de desplazamiento vertical y horizontal (respectivamente).
void setViewportView(Component)
Selecciona el cliente del ScrollPane.
Implementar el Interface Scrollable
Mtodo
Propsito
int getScrollableUnitIncrement(Rectangle, int, int)
void getScrollableBlockIncrement(Rectangle, int, int)
Obtiene el incremento de unidad o de bloque en pixels. El parmetro Rectangle son
los lmites del rea visible actualmente. El primer parmetro int es
SwingConstants.HORIZONTAL o SwingConstants.VERTICAL dependiendo de la barra que
haya pulsado el usuario. El segundo parmetro int indica la direccin del desplazamiento.
Un valor menor que 0 indica arriba o izquierda. Una valor mayor que 0 indica abajo o
derecha.
Dimension getPreferredScrollableViewportSize()
Obtiene el tamao preferido del
JViewport. Esto permite al cliente influenciar en el tamao del componente en el que va
ser mostrado. Si este tamao no es importante devuelve getPreferredSize.
boolean getScrollableTracksViewportWidth()
boolean getScrollableTracksViewportHeight()
Obtiene su el ScrollPane debera forzar al cliente a tener la misma anchura o altura
que el JViewport. Devolver true por alguno de esto mtodos efectivamente desactiva el
desplazamiento horizontal o vertival (respectivamente).
_________________________________________
JPanel con JScrollPane
En uno de mis proyectos he tenido el inconveniente de cargar datos en un jpanel (por lo
visto algo muy fuera de lo normal, ya que no haba solucin clara) tenindolo dentro de
un jscrollpane no se llegaba a visualizarse mas que lo que abarcaba el tamao del panel,
vamos que el scroll no apareca y por mas que refrescaba con getGraphics(); no haba
manera.
Descubr por ah el siguiente mtodo de los JPanel setPreferredSize(); una bendicin ya
que es la solucin a mis problemas. Aqu os dejo como quedara el cdigo:
JPanel panel = new JPanel();
JScrollPane scroll = new JScrollPane();
scroll .setBounds(132, 155, 502, 311);
scroll .setViewportView(panel);
scroll .getViewport().setView(panel);
panel.setLayout(null);
Creamos el jpanel creamos el jscrollpane definimos un tamao al scroll y metemos en el
scroll el panel. Por ltimo el proceso de carga de datos usamos incluiremos:
panel.setPreferredSize(new Dimension(480,600);
Vamos variando los valores X, Y dependiendo de cuanto necesitamos para mostrar. El
cdigo de arriba variara ya que se supone el el jscrollpane estar en un jFrame, jDialog...
10

NOTA: parecer una tontera pero buscar en internet a ver si hay algo referenciando a
esta solucin, por que a m me a costado. Espero que para la prxima el siguiente que lo
necesite lo encuentre antes de perder los nervios ;)
_________________________________
Manos a la obra
Nuevamente nos basaremos en el esquema MVC (Modelo, Vista, Controlador) para la
construccin del software, comenzando con la parte de la vista para nuestra ventana y
nuestros paneles de opciones.
Componentes de la interfaz de usuario:
JSlider. Utilizaremos este componente para crear una pequea paleta de intensidad de
colores y otra de intensidad del brillo, de forma que podamos modificar con los tonos de
rojo, verde y azul de las imgenes, as como el brillo que estas proyectan.
JPanel. Utilizaremos este componente primero, para crear todos los paneles en los que se
cargarn los componentes, y adems crearemos una clase llamada PanelDeImagen que
extender a la clase JPanel, para que funcione como un lienzo sobre el cual dibujaremos
las imgenes que carguemos y editemos en la aplicacin.
JScrollPane. Ya que el tamao de las imgenes puede varias respecto del tamao de la
ventana de nuestra aplicacin, utilizaremos un panel de tipo JScrollPane, el cual tiene la
caracterstica de hacer aparecer barras de desplazamiento en sus bordes cuando su
contenido excede a su tamao en pantalla, de forma que podemos cargar imgenes ms
grandes que nuestra ventana sin problemas.
JMenuBar, JMenu y JMenuItem. Estos componentes nos permitirn crear una barra de
men en el panel superior de nuestra aplicacin, el cual contendr las opciones
relacionadas con los archivos, como son abrir un archivo de imagen, guardar la imagen
editada, salir de la aplicacin. Tambin permitirn activar los paneles que contendrn las
opciones para la edicin de nuestras imgenes.
JFileChooser. Este componente adicional, nos auxiliar para hacer ms sencilla la
seleccin y el guardado de archivos de imgenes, ya que con los objetos de esta clase
podemos llamar una ventana de seleccin de archivos, que nos permitir elegir los
archivos que editaremos en nuestra aplicacin de forma visual.
La Vista
El cdigo para implementar la vista de la aplicacin aparecer a continuacin, separando
cada una de las clases en un apartado.
Cdigo para la implementacin de la ventana de la aplicacin:
EditorImg.java
import java.awt.*;import java.awt.event.*;import javax.swing.*;
/** * Descripcin: Esta clase implementa un editor bsico de imgenes .jpg y .gif, *
utilizando componentes Swing y una serie de clases para el manejo y procesamiento de
imagenes digitales. * @author Beto Gonzlez * @version 1.0 * @category Multimedia */
public class EditorImg extends JFrame{ static final long serialVersionUID=10000;
PanelSwing panel;
11

// TODO Auto-generated method stub


public static void main(String[] args) {
EditorImg editor = new EditorImg();
editor.setBounds(120, 120, 800, 600);
editor.setVisible(true);
editor.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
editor.addWindowListener(new WindowAdapter() {
public void WindowCloser(WindowEvent e) {
System.exit(0); } }); }
/** * @Desc Constructor de la clase */
EditorImg() { super("Editor bsico de imagenes");
Container contentPane = getContentPane();
panel = new PanelSwing(this);
contentPane.add(panel);
}
}
Cdigo para implementar el lienzo sobre el que se dibujar la imagen:
PanelDeImagen.java
import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import
java.awt.Image;import javax.swing.JPanel;import javax.swing.JScrollPane;
/** * @Desc Clase que extiende a la clase JPanel que se utiliza para crear un panel que
permita visualizar imgenes en su interior * @author Beto Gonzlez * */
public class PanelDeImagen extends JPanel{ static final long serialVersionUID=10000;
Image img; Dimension tamao; JScrollPane base;
/** * @Desc Constructor de la clase */
PanelDeImagen() { setBackground(Color.white); }
/** * @Desc Mtodo a travs del cual la clase recibe el objeto de la imagen que ser
visualizada en su interior * @param i */
public void estableceImagen(Image i) {
img = i; }
/** * @Desc Mtodo a travs del cual la clase obtiene la referencia hacia el panel en el
cual se encuentra contenido. * @param i */
public void estableceBase(JScrollPane contenedor) { base = contenedor; }
/** * @Desc Mtodo extendido que es llamado cada ves que un objeto de esta clase
llama al mtodo repaint(). A este le agregamos * una funcionalidad adicional que le
permite redimencionar el panel que contiene la imagen de acuerdo a las dimensiones de
* sta */
public void paintComponent(Graphics g) { super.paintComponent(g);
if (img != null) {
if(base != null) {
setSize(new Dimension(base.getWidth()-10,base.getHeight()-10));
setPreferredSize(new Dimension(base.getWidth()-10,base.getHeight()-10));
}
tamao = new Dimension(getWidth(),getHeight());
int x = tamao.width - img.getWidth(this);
while (x < 0) { tamao.setSize(tamao.width+1, tamao.height);
x = tamao.width - img.getWidth(this); } if(x > 0)
x = (int) x/2;
int y = tamao.height - img.getHeight(this); while (y < 0) {
tamao.setSize(tamao.width, tamao.height+1);
y = tamao.height - img.getHeight(this);
12

}
if(y > 0)
y = (int) y/2;
if(!getSize().equals(tamao)) {
setPreferredSize(tamao);
}
g.drawImage(img, x, y, this);
}
}
}

setSize(tamao);

La funcionalidad de los objetos de la clase PanelDeImagen consistir en que recibirn una


imagen por medio del mtodo estableceImagen() y la dibujarn en su panel al llamar al
mtodo repaint() que heredaron de la clase JPanel. Ya que en esta implementacin el
panel de las imagenes estar contenida dentro de un objeto JScrollPane, es que adems
contamos con el mtodo estableceBase(), con el cual podemos guardar una referencia a
este panel. Adems, debido a que las dimensiones de las imagenes cargada por la
aplicacin pueden, es que extendimos al mtodo paintComponent(), el cul adems de
encargarse de dibujar la imagen dentro del panel, modificar las dimensiones de este y
del panel JScrollPane que lo contenga, de forma que se adapten al tamao de las
imgenes y estas puedan ser visualizadas en su totalidad en pantalla.
La siguiente clase implementa la totalidad de los componentes de la interfaz grfica de la
aplicacin:
PanelSwing.java
import java.awt.*;import javax.swing.*;import javax.swing.event.ChangeEvent;import
javax.swing.event.ChangeListener;
/** * @Desc Clase utilizada para crear los componentes de la interfaz grfica de la
aplicacin * @author Beto Gonzlez * */
public class PanelSwing extends JPanel { static final long serialVersionUID = 10000;
String nombreArchivo, ruta;
JMenuBar barraMenu;
JMenu menuArchivo, menuEdicion;
JMenuItem abrir, guardar, salir, brillo, color, escala;
JScrollPane panelDespl;
JPanel panelBajo, panelBrillo, panelColor, panelVacio;
int altura = 80; Image imagen;
Image imgAux; EditorImg editor;
PanelDeImagen lienzo;
JSlider jslBrillo, jslRojo, jslVerde, jslAzul;
JLabel lblRojo, lblVerde, lblAzul;
CardLayout esqueInf;
/** * @Desc Constructor de la clase * @param editor */
PanelSwing(EditorImg editor) {
this.editor = editor;
this.setLayout(new BorderLayout());
barraMenu = new JMenuBar();
FlowLayout f = new FlowLayout();
f.setAlignment(FlowLayout.LEFT);
barraMenu.setLayout(f);
13

menuArchivo = new JMenu("Archivo");


menuEdicion = new JMenu("Edicin");
abrir = menuArchivo.add("Abrir");
guardar = menuArchivo.add("Guardar");
guardar.setEnabled(false);
menuArchivo.addSeparator();
salir = menuArchivo.add("Salir");
brillo = menuEdicion.add("Ajustar Brillo");
color = menuEdicion.add("Ajustar Colores");
escala = menuEdicion.add("Escala de Grises");
brillo.setEnabled(false);
color.setEnabled(false);
escala.setEnabled(false);
barraMenu.add(menuArchivo);
barraMenu.add(menuEdicion);
this.add("North",barraMenu);
//Agregamos la barra de menu
creapanelCentral();
//Creamos el panel en el que se mostrara la imagen seleccionada
creapanelBajo();
//Creamos el panel en el que se mostraran los controles para manipular la imagen
/** * @Desc Mtodo que crea el contenido del panel central de la ventana */
private void creapanelCentral() {
lienzo = new PanelDeImagen();
panelDespl = new JScrollPane(lienzo);
lienzo.estableceBase(panelDespl);
add("Center",panelDespl);
}
/** * @Desc Mtodo que crea el contenido del panel inferior de la ventana */
private void creapanelBajo() { panelBajo = new JPanel();
esqueInf = new CardLayout();
panelBajo.setLayout(esqueInf);
panelBajo.setPreferredSize(new Dimension(this.getWidth(),altura));
jslBrillo = new JSlider(SwingConstants.HORIZONTAL,0,100,0);
jslBrillo.setPaintTicks(true);
jslBrillo.setPaintLabels(true);
jslBrillo.setMajorTickSpacing(10);
jslBrillo.setMinorTickSpacing(5);
panelColor = new JPanel();
panelVacio = new JPanel();
panelBrillo = new JPanel(new BorderLayout());
panelBrillo.add("Center",
new
JLabel("Puedes
ajustar
el
brillo
imagen",JLabel.CENTER));
panelBrillo.add("South",jslBrillo);
panelBajo.add("carta1", panelVacio);
panelBajo.add("carta2", panelBrillo);
creaPaletas();
esqueInf.show(panelBajo, "carta1");
this.add("South",panelBajo);
}
/** * @Desc Mtodo que crea el contenido del panel inferior de la ventana */
private void creaPaletas() {
14

de

la

GridBagLayout gridbag = new GridBagLayout();


GridBagConstraints constrain = new GridBagConstraints();
panelColor.setLayout(gridbag); lblRojo = new JLabel("Rojo");
lblVerde = new JLabel("Verde");
lblAzul = new JLabel("Azul");
constrain.gridx = 0; constrain.gridy = 0;
constrain.gridheight = 1; constrain.gridwidth = 2;
gridbag.setConstraints(lblRojo, constrain);
panelColor.add(lblRojo); constrain.gridx = 2;
constrain.gridy = 0;
gridbag.setConstraints(lblVerde, constrain);
panelColor.add(lblVerde);
constrain.gridx = 4;
constrain.gridy = 0;
gridbag.setConstraints(lblAzul, constrain);
panelColor.add(lblAzul); jslRojo = new JSlider(SwingConstants.HORIZONTAL,0,50,0);
jslVerde = new JSlider(SwingConstants.HORIZONTAL,0,50,0);
jslAzul = new JSlider(SwingConstants.HORIZONTAL,0,50,0);
constrain.gridx = 0;
constrain.gridy = 1;
constrain.gridheight = 1;
constrain.gridwidth = 2;
gridbag.setConstraints(jslRojo, constrain);
panelColor.add(jslRojo);
constrain.gridx = 2;
constrain.gridy = 1;
gridbag.setConstraints(jslVerde, constrain);
panelColor.add(jslVerde);
constrain.gridx = 4;
constrain.gridy = 1;
gridbag.setConstraints(jslAzul, constrain);
panelColor.add(jslAzul);
panelBajo.add("carta3", panelColor);
}
}
Hasta este punto hemos completado la parte de la Vista de la aplicacin, y nos quedan
pendientes el Controlador y el Modelo. Sin embargo, para poder apreciar realmente la
funcionalidad de las clases anteriores es necesario probarlas, echando a correr el
programa, de forma que podamos visualizarlas y obtener un resultado como el siguiente:
En esta captura, podemos apreciar los tres paneles principales de la aplicacin, el men
de opciones en la parte superior, el panel central que contiene los paneles de los
componentes de las clases JScrollPane y PanelDeImagen, y finalmente el panel inferior, en
el cual se desplegarn los componentes visuales para la edicin de las imagenes, una vez
que el Controlador y el Modelo estn trabajando.
Ahora terminaremos con el cdigo que qued pendiente en el artculo anterior, que
consiste en la programacin del Controlador y el Modelo de nuestra aplicacin.

15

El Controlador tendr la obligacin de manejar los eventos que ocurran en la interfaz de


usuario, de modo que recibir las acciones del usuario en el men de opciones y las
paletas de edicin, los cuales ya creamos en el artculo anterior.
Por otro lado, el Modelo tendr responsabilidades a ms bajo nivel, encargndose de
implementar la carga, la edicin y el guardado de las imgenes. Separando las diferentes
funcionalidades en dos capas de nivel distinto, como si de las capas de Negocio y Acceso
a datos se tratara.
El Controlador
El Controlador de la aplicacin consistir en una nica clase que implementar las
interfaces ActionListener y ChangeListener, para implementar en control de eventos del
men y de las barras JSlider respectivamente.
El cdigo es el siguiente:
Controlador.java
import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import
javax.swing.JMenuItem;import javax.swing.JSlider;import
javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;import
javax.swing.JPanel;
/** * @Desc Clase que implementa la gestin de evento en la interfaz de usuario *
@author Beto Gonzlez * */
public class Controlador implements ActionListener, ChangeListener{
ManejadorDeImagenes manejador;
PanelSwing panel;
public Controlador(PanelSwing panel) {
this.panel = panel; manejador = new ManejadorDeImagenes();
}
/** * @Desc Mtodo que capturar los eventos ocurridos en el men principal del
sistema */
public void actionPerformed(ActionEvent ie) {
JMenuItem i = (JMenuItem)ie.getSource();
if(i.getText() == "Abrir"){
boolean estado = manejador.cargaArchivoDeImagen(panel, panel.lienzo);
if(estado) {
panel.guardar.setEnabled(true);
panel.brillo.setEnabled(true);
panel.color.setEnabled(true);
panel.escala.setEnabled(true);
panel.esqueInf.show(panel.panelBajo, "carta1");
}
}
else if(i.getText() == "Guardar")
manejador.guardaArchivoDeImagen(panel);
else if(i.getText() == "Salir")
System.exit(0);
else if(i.getText() == "Ajustar Brillo") {
manejador.restableceImagen(panel.lienzo);
panel.jslBrillo.setValue(0);
16

panel.esqueInf.show(panel.panelBajo, "carta2");
}
else if(i.getText() == "Ajustar Colores") {
manejador.restableceImagen(panel.lienzo);
panel.esqueInf.show(panel.panelBajo, "carta3");
}
else if(i.getText() == "Escala de Grises") {
panel.esqueInf.show(panel.panelBajo, "carta1");
manejador.muestraEscalaDeGrises(panel.lienzo);
}
}
/** * @Desc Mtodo que captarar los eventos ocurridos en los componentes JSlider de
la interfaz de usuario */
public void stateChanged(ChangeEvent e) {
JSlider slider = (JSlider) e.getSource();
if(slider == panel.jslBrillo) manejador.muestraBrillo(panel.lienzo, slider.getValue());
else if(slider == panel.jslRojo) {
manejador.muestraColores(panel.lienzo, slider.getValue(), panel.jslVerde.getValue(),
panel.jslAzul.getValue());
}
else if(slider == panel.jslVerde)
manejador.muestraColores(panel.lienzo, panel.jslRojo.getValue(), slider.getValue(),
panel.jslAzul.getValue());
else if(slider == panel.jslAzul)
manejador.muestraColores(panel.lienzo, panel.jslRojo.getValue(),
panel.jslVerde.getValue(), slider.getValue());
}
}
Como podemos ver, en la implementacin del mtodo actionPerformed() lleva a cabo las
acciones relacionadas con el men de opciones, tanto para las acciones de la opcin
"Archivo" (Abrir, Guardar y Salir) como para la "Edicin" (Ajustar Brillo, Ajustar Colores,
Escala de Grises). Las opciones de edicin solo se activarn una vez que un archivo de
imagen haya sido cargado por el editor, para lo cual se apoyar en un objeto de la clase
ManejadorDeImagenes, la cual veremos ms adelante.
En la implementacin del mtodo stateChanged(), se reciben las acciones ocurridas en los
controles de tipo JSlider, de forma que podremos capturar el valor del brillo o los colores
que el usuario capture en la interface, y llamar a alguno de los mtodos del objeto de la
clase ManejadorDeImagenes para aplicar estos cambios a las imagenes cargadas.
El Modelo
Como ya explicamos antes, el modelo consistir estar separado en dos capas, que en la
programacin veremos expresado como dos clases diferentes. La primera
ManejadorDeImagenes, que equivaldr a la capa de negocio en las aplicaciones de
manejo de datos. Esta clase ser un intermediario entre el Controlador y la Vista de la
aplicacin con el nivel de Acceso a datos, que en este caso consiste en la apertura,
modificacin y salvado de las imgenes. Estas operaciones de bajo nivel sern llevadas a
cabo por la clase ProcesadorDeImagenes, la cual estar completamente abstrada del
resto de la aplicacin, ya que en ella ocurrirn las operaciones a nivel de pixeles sobre las
17

imgenes, y adems poseer mtodos para cargar una imagen desde el archivo y salvar
las imgenes resultantes del procesamiento hacia un archivo nuevo.
El cdigo de la primera de estas clases aparece a continuacin:
ManejadorDeImagenes.java
import java.awt.*;import javax.swing.JFileChooser;import javax.swing.JOptionPane;import
javax.swing.JPanel;
/** * @Desc Clase del nivel de la capa de negocios, que implementa las operaciones que
son llamadas desde el Controlador de la aplicacin * para poder cargar las imagenes,
alamacenarlas y modificaralas, apoyandose en un objeto la clase de ms bajo nivel, es
decir ProcesadorDeImagenes * @author Beto Gonzlez * */
public class ManejadorDeImagenes {
ProcesadorDeImagenes procesador;
boolean editado = false;
// Constructor de la clase public
ManejadorDeImagenes() {
procesador = new ProcesadorDeImagenes();
}
/** * @Desc Mtodo que lleva a cabo la carga de un archivo de imagen * @param
contenedor * @param lienzo * @return */
public boolean cargaArchivoDeImagen(JPanel contenedor, PanelDeImagen lienzo) {
String nombreArchivo = "";
boolean estado = true;
if(editado) {
new MsgError("Confirmacion","Aqui debemos pedir confirmacin",200,180);
int resultado = JOptionPane.showConfirmDialog((Component)null, "Deseas guardar los
cambios en este documento?","Confirmacin",JOptionPane.YES_NO_OPTION);
if(resultado==JOptionPane.YES_OPTION) guardaArchivoDeImagen(contenedor);
}
JFileChooser selector = new JFileChooser();
selector.addChoosableFileFilter(new FiltrodeArchivo("gif","Archivos Gif"));
String lista[] = {"jpeg","jpg"};
selector.addChoosableFileFilter(new FiltrodeArchivo(lista,"Archivos JPEG"));
selector.setDialogTitle("Abrir archivo de imagen");
selector.setDialogType(JFileChooser.OPEN_DIALOG);
int resultado = selector.showOpenDialog(null);
if(resultado == JFileChooser.APPROVE_OPTION) { nombreArchivo =
selector.getSelectedFile().getName();
String ruta = selector.getSelectedFile().getPath();
Image imagen = procesador.cargaImagen(ruta, nombreArchivo);
lienzo.estableceImagen(imagen);
lienzo.repaint();
editado = false; } else estado = false; return estado;
}
/** * @Desc Mtodo que lleva a cabo la operacin de salvar el archivo de imagen
cargado * @param contenedor * @return */
public boolean guardaArchivoDeImagen(JPanel contenedor) {
boolean estado = true; JFileChooser selector = new JFileChooser();
selector.addChoosableFileFilter(new FiltrodeArchivo("gif","Archivos Gif"));
String lista[] = {"jpeg","jpg"};
selector.addChoosableFileFilter(new FiltrodeArchivo(lista,"Archivos JPEG"));
18

selector.setDialogTitle("Guardar archivo de imagen");


selector.setDialogType(JFileChooser.SAVE_DIALOG);
int resultado = selector.showSaveDialog(contenedor);
if(resultado == JFileChooser.APPROVE_OPTION) {
//guardar archivo en la ruta especificada
String nombreArchivo = selector.getSelectedFile().getName();
String ruta = selector.getSelectedFile().getPath();
estado = procesador.guardaImagen(ruta, nombreArchivo);
if(!estado) JOptionPane.showMessageDialog((Component)null,"Error del sistema :
"+procesador.devuelveMensajeDeError(),"Error de Imagen",JOptionPane.OK_OPTION);
editado = false;
} else estado = false;
return estado;
}
/** * @Desc Mtodo que lleva a cabo la transformacin de la imagen cargada a una
imagen de escala de grises y la despliega en pantalla * @param lienzo */
public void muestraEscalaDeGrises(PanelDeImagen lienzo) {
procesador.escalaDeGrises();
lienzo.estableceImagen(procesador.devuelveImagenModificada());
lienzo.repaint();
}
/** * @Desc Mtodo que lleva a cabo la modificacin del brillo de la imagen cargada y
despliega la imagen resultante en pantalla * @param lienzo * @param valor */
public void muestraBrillo(PanelDeImagen lienzo, int valor) {
procesador.modificaBrillo(valor);

lienzo.estableceImagen(procesador.devuelveImagenModificada());
lienzo.repaint(); editado = true;
}
/** * @Desc @Desc Mtodo que lleva a cabo la modificacin de los colores de la imagen
cargada y despliega la imagen resultante en pantalla * @param lienzo * @param rojo *
@param verde * @param azul */
public void muestraColores(PanelDeImagen lienzo, int rojo, int verde, int azul) {
procesador.modificaColor(rojo,verde,azul);
lienzo.estableceImagen(procesador.devuelveImagenModificada());
lienzo.repaint(); editado = true;
}
/** * @Desc Mtodo que coloca en la pantalla la imagen original que se carg con el
mtodo cargarArchivoDeImagen * @param lienzo */
public void restableceImagen(PanelDeImagen lienzo)
{ lienzo.estableceImagen(procesador.devuelveImagenBase());
lienzo.repaint(); editado = false;
}
}
Como vemos en los mtodos cargaArchivoDeImagen() y guardaArchivoDeImagen(), la
funcionalidad para elegir los archivos que sern cargados y guardados se facilita con el
19

uso de la clase JFileChooser, la cual permite llamar a una ventana de seleccin de


archivos, con la cual resulta ms agradable esta tarea.
Tambin podemos apreciar que se utiliza un objeto de la clase FiltroDeArchivo, para
establecer el filtro que tendr el objeto selector de la clase JFileChooser. De esta forma
nos aseguramos que solo puedan ser seleccionadas imgenes de tipo JPEG y GIF. El
cdigo de esta clase auxiliar aparece a continuacin:
FiltroDeArchivo.java
import java.io.*;/** * @Desc Clase que permite crear un filtro de archivos para utilizarlo
con un selector de archivos * @author Beto Gonzlez * */
public class FiltrodeArchivo extends javax.swing.filechooser.FileFilter {
String descrip = "";
String listTipos[];
FiltrodeArchivo(String tipo, String descripcion) {
listTipos = new String[1];
listTipos[0] = tipo; descrip = descripcion;
}
FiltrodeArchivo(String listTipos[], String descripcion) {
this.listTipos = listTipos; descrip = descripcion;
}
public boolean accept(File fileobj){
boolean extIgual = false; String extension = "";
int ind=0; if(fileobj.getPath().lastIndexOf(".") > 0) {
extension = fileobj.getPath().substring(fileobj.getPath().lastIndexOf(".")
+1).toLowerCase();
}
if(extension!="") {
while(ind<listTipos.length && !extIgual) {
extIgual = extension.equals(listTipos[ind].toLowerCase());
ind++;
}
return extIgual;
}
else return fileobj.isDirectory();
}
public String getDescription() {
if (descrip != "")
return descrip.concat(concatTipos());
else return "";
} private String concatTipos() {
StringBuffer tipos = new StringBuffer(" (*."+listTipos[0]);
for(int i=1;i<listTipos.length;i++)
tipos.append(",*."+listTipos[i]);
tipos.append(")");
return tipos.toString(); }}
Tanto estos dos mtodos como el resto sern llamados desde el Controlador de la
aplicacin para cada accin que el usuario vaya realizando en la interfaz grfica. De modo
que el mtodo muestraEscalaDeGrises() ser llamado cuando el usuario seleccione la
opcion "Escala de Grises" en el men principal. Mientas que el mtodo muestraBrillo() es
20

llamado cuando el usuario realice un cambio en el brillo de la imagen, utilizando la barra


JSlider jslBrillo para ajustar el brillo. Algo similar ocurrir con el mtodo muestraColores(),
que se llamar cuando alguna de las barras JSlider de colores (jslRojo, jslVerde, jslAzul)
sea utilizada. Estos mtodos adems llevan a cabo la actualizacin en la pantalla de las
imgenes una vez que son modificadas. En el caso de que el usuario aumente el brillo o
modifique los colores, la accin ocurrir tan rpido que no podr darse cuenta de todo el
trabajo que la PC llev a cabo para cambiar la apariencia de la imagen capturada.
El mtodo restableceImagen() se utiliza para volver a colocar en la pantalla la imagen
original que fue cargada, lo cual es simplemente una forma de asegurarnos que las tres
acciones de edicin (aumentar brillo, modificar colores y convertir a escala de grises)
siempre ocurran sobre la misma imagen que fue cargada.
El cdigo de la clase ProcesadorDeImagenes a la que nos hemos referido aparece a
continuacin:
ProcesadorDeImagenes.java
import java.awt.Canvas;import java.awt.image.*;import java.awt.Image;import
java.awt.Toolkit;import java.io.IOException;import java.io.File;import
java.awt.Graphics;import java.awt.image.BufferedImage;import javax.imageio.ImageIO;
/** * @Desc Clase que implementa el procesamiento bsico de imgenes digitales *
@author Beto Gonzlez * */
public class ProcesadorDeImagenes extends Canvas {
Image imagenBase; Image imagenModificada;
String mensajeDeError = "";
String tipoDeImagen = "";
/** * @Desc Mtodo que permite agregar una imagen al procesador que es recibida
como parmetro * @param imagen */
public void estableceImagen(Image imagen) {
imagenBase = imagen;
imagenModificada = null;
tipoDeImagen = (String)imagenBase.getProperty("type", this);
}
/** * @Desc Mtodo que permite agregar una imagen al procesador directamente desde
un archivo de imagen * @param imagen */
public Image cargaImagen(String ruta, String nombreDeArchivo) {
imagenBase = Toolkit.getDefaultToolkit().getImage(ruta);
imagenModificada = null; String[] partes = null;
partes = nombreDeArchivo.split("\\.");
int tope = partes.length;
if(tope > 1) tipoDeImagen = partes[tope - 1];
return imagenBase;
}
/** * @Desc Mtodo que modifica el brillo de la imagen base contenida a partir del valor
de intesidad recibido * @param intensidad * @return Verdadero si todo sali bien, falso
en caso de error */
public boolean modificaBrillo(int intensidad) {
boolean estado = true;
int p, rojo, verde, azul;
int a = imagenBase.getWidth(this);
21

//Ancho
int h = imagenBase.getHeight(this);
//Alto
int totalDePixeles = a * h;
int pixeles[] = new int[totalDePixeles];
//Arreglo de pixeles
PixelGrabber pg = new PixelGrabber(imagenBase,0,0,a,h,pixeles,0,a);
try { pg.grabPixels();
for(int i = 0;
i < totalDePixeles; i++) {
p = pixeles[i];
//Valor de un pixel
rojo = (0xff & (p>>16)) + intensidad;
//Desplaza el entero p 16 bits a la derecha y aplica la operacion AND a los primeros 8 bits
verde = (0xff & (p>>8)) + intensidad;
//Desplaza el entero p 8 bits a la derecha y aplica la operacion AND a los siguientes 8
bits
azul = (0xff & p) + intensidad;
//Aplica la operacion AND a los siguientes 8 bits
if(rojo>255) rojo=255;
if(verde>255) verde=255;
if(azul>255) azul=255;
if(rojo<0) rojo=0; if(verde<0) verde=0; if(azul<0) azul=0; pixeles[i]=(0xff000000|
rojo<<16|verde<<8|azul);
}
imagenModificada = createImage(new MemoryImageSource(a,h,pixeles,0,a));
}
catch(InterruptedException e) {
JOptionPane.showMessageDialog((Component)null,"Error del sistema :
"+e.getMessage(),"Error de Imagen",JOptionPane.OK_OPTION);
estado = false;
this.mensajeDeError = e.getMessage();
}
return estado;
}
/** * @Desc Mtodo que convierte la imagen base contenida en una imagen a escala de
grises * @return Verdadero si todo sali bien, falso en caso de error */
public boolean escalaDeGrises() {
boolean estado = true;
int p, promedio, rojo, verde, azul;
int a = imagenBase.getWidth(this);
//Ancho
int h = imagenBase.getHeight(this);
//Alto
int totalDePixeles = a * h; int pixeles[] = new int[totalDePixeles];
//Arreglo de pixeles
PixelGrabber pg = new PixelGrabber(imagenBase,0,0,a,h,pixeles,0,a);
try {
pg.grabPixels();
for(int i = 0; i < totalDePixeles; i++) {
p = pixeles[i];
22

//Valor de un pixel
rojo = (0xff & (p>>16));
//Desplaza el entero p 16 bits a la derecha y aplica la operacion AND a los primeros 8 bits
verde = (0xff & (p>>8));
//Desplaza el entero p 8 bits a la derecha y aplica la operacion AND a los siguientes 8
bits
azul = (0xff & p) ;
//Aplica la operacion AND a los siguientes 8 bits
promedio = (int) ((rojo+verde+azul)/3);
pixeles[i]=(0xff000000|promedio<<16|promedio<<8|promedio);
}
imagenModificada = createImage(new MemoryImageSource(a,h,pixeles,0,a));
}
catch(InterruptedException e) {
//JOptionPane.showMessageDialog((Component)null,"Error del sistema :
"+e.getMessage(),"Error de Imagen",JOptionPane.OK_OPTION);
estado = false;
this.mensajeDeError = e.getMessage();
}
return estado;
}
/** * @Desc Mtodo que modifica los colores de la imagen base contenida a partir de los
valores de intensidad de los colores rojo, verde y amarillo recibidos * @param iRojo *
@param iVerde * @param iAzul * @return Verdadero si todo sali bien, falso en caso de
error */
public boolean modificaColor(int iRojo, int iVerde, int iAzul) {
boolean estado = true;
int p, rojo=0, verde=0, azul=0;
int a = imagenBase.getWidth(this);
//Ancho
int h = imagenBase.getHeight(this);
//Alto
int totalDePixeles = a * h;
int pixeles[] = new int[totalDePixeles];
//Arreglo de pixeles
PixelGrabber pg = new PixelGrabber(imagenBase,0,0,a,h,pixeles,0,a);
try {
pg.grabPixels();
for(int i = 0;i<(a*h);i++) {
p = pixeles[i];
//Valor de un pixel
rojo = (0xff & (p>>16)) + iRojo;
verde = (0xff & (p>>8)) + iVerde;
azul = (0xff & p) + iAzul;
if(rojo>255) rojo=255;
if(verde>255) verde=255;
if(azul>255) azul=255;
if(rojo<0) rojo=0;
if(verde<0) verde=0;
if(azul<0) azul=0;
pixeles[i]=(0xff000000|rojo<<16|verde<<8|azul);
}
23

imagenModificada = createImage(new MemoryImageSource(a,h,pixeles,0,a));


}
catch(InterruptedException e) {
estado = false;
this.mensajeDeError = e.getMessage();
}
return estado;
}
/** * @Desc Mtodo que almacena la imagen contenida en una archivo de imagen, de
acuerdo a la informacin del archivo que recibe como parmetro * @param ruta *
@param nombreDeArchivo * @param tipoDeImagen * @return */
public boolean guardaImagen(String ruta, String nombreDeArchivo, String tipoDeImagen)
{
boolean estado = true;
BufferedImage imagen = creaBufferedImage((imagenModificada != null) ?
imagenModificada : imagenBase);
try {
ImageIO.write(imagen, tipoDeImagen, new File(ruta));
}
catch (IOException e) {
estado = false;
this.mensajeDeError = e.getMessage();
}
return estado;
}
/** * @Desc Versin por defecto del mtodo guardaImagen * @param ruta * @param
nombreDeArchivo * @return */
public boolean guardaImagen(String ruta, String nombreDeArchivo) { String[] partes =
null; partes = nombreDeArchivo.split("\\.");
int tope = partes.length;
if(tope > 1) tipoDeImagen = partes[tope - 1];
return guardaImagen(ruta, nombreDeArchivo, tipoDeImagen);
}
/** * @Desc Mtodo que devuelve la imagen modificada por el procesador en un objeto
de la clase Image * @return */
public Image devuelveImagenModificada() { return imagenModificada;
}
/** * @Desc Mtodo que devuelve la imagen base dentro de un objeto de la clase Image
* @return */
public Image devuelveImagenBase() { return imagenBase;
}
/** * @Desc Mtodo que retora el ltimo mensaje de error producido por los mtodos de
la clase * @return */
public String devuelveMensajeDeError() { return mensajeDeError;
}
/** * @Desc Versin por defecto del mtodo creaBufferedImage * @param imageIn *
@return El objeto BufferedImage */
public BufferedImage creaBufferedImage(Image imagenDeEntrada) {
return creaBufferedImage(imagenDeEntrada, BufferedImage.TYPE_INT_RGB);
}
/** * @Desc Mtodo para convertir un objeto Image a un objeto BufferedImage *
@param imageIn * @param imageType * @return El objeto BufferedImage */
24

public BufferedImage creaBufferedImage(Image imagenDeEntrada, int imageType) {


BufferedImage bufferedImageDeSalida = new
BufferedImage(imagenDeEntrada.getWidth(this),imagenDeEntrada.getHeight(this),
imageType);
Graphics g = bufferedImageDeSalida.getGraphics();
g.drawImage(imagenDeEntrada, 0, 0, null);
return bufferedImageDeSalida; }}
Como ya mencionamos esta clase trabajo al nivel ms bajo de la aplicacin directamente
con los pixeles de las imagenes. Para lograr esto utiliza dos objetos de las clase Image
(imagenBase e imagenModificada), para almacenar tanto las imgenes que son ledas
tanto como la imagen que resulta del procesamiento (respectivamente). Los mtodos
estableceImagen() y cargarImagen() le permiten tener una imagen sobre la cual llevar a
cabo el procesamiento que ocurre en los otros mtodos.
Los mtodos modificaBrillo(), escalaDeGrises() y modificaColores() llevan a cabo los
cambios en los pixeles de la imagen, aplicando una serie de operaciones a cada uno de
sus valores de intensidad de color, almacenando los valores de los pixeles dentro de un
arreglo de nmero enteros y recorrindolo dentro de un ciclo for. De esta forma, cada uno
de los pixeles es tratado como un nmero entero, para el cual los valores de la intensidad
del color estarn contenidos en sus primeros tres grupos de 8 bits. Es decir, los primero 8
bits menos significativos del entero representarn la intensidad del azul, los siguientes 8
bits los del verde y los 8 bits que le siguen los del rojo. Es por esto que en el cdigo
vemos que se lleva a cabo un desplazamiento a nivel de bits del valor de un pixel, para
junto con la operacin AND obtener los 8 bits del valor de cada uno de los tres colores del
pixel:

p = pixeles[i];
//Valor de un pixel
rojo = (0xff & (p>>16)) + intensidad;
//Desplaza el entero p 16 bits a la derecha y aplica la operacion AND a los primeros 8 bits
verde = (0xff & (p>>8)) + intensidad;
//Desplaza el entero p 8 bits a la derecha y aplica la operacion AND a los siguientes 8 bits
azul = (0xff & p) + intensidad;
//Aplica la operacion AND a los siguientes 8 bits
El cdigo anterior es el que encontramos en el mtodo modificaBrillo(), y lo que vemos
que se hace es justamente sumarle una misma cantidad a cada uno de los valores de
color del pixel para de esta forma obtener un pixel ms iluminado, para despus
almacenar este pixel obtenido dentro del arreglo de pixeles.
En los otros dos mtodos se sigue una lgica parecida, con la nica diferencia de que para
modificaColores, se aumentar la intensidad de los colores de los pixeles con un valor
distinto para cada color, mientras que en escalaDeGrises se promediar el valor de los
tres colores de cada pixel y se almacenar el mismo resultado dentro de los tres valores
25

de color del pixel, para de esta forma obtener el equivalente en escala de grises del color
original.
Implementacin final
Ahora bien, visto el cdigo del Controlador y el Modelo de la aplicacin, solo nos queda
juntarlo todo con la Vista para echar a correr el programa final. Para hacer eso, tendremos
que modificar el cdigo de la clase EditorImg que realizamos en el artculo anterior,
agregando las lneas que se remarcan en el siguiente cdigo:
EditorImg.java
import java.awt.*;import java.awt.event.*;import javax.swing.*;/** * Descripcin: Esta
clase implementa un editor bsico de imagenes .jpg y .gif, * utilizando componentes
Swing y clases de la libreria image. * @author Alberto Gonzlez Espinoza * @version 1.0 *
@category Multimedia */
public class EditorImg extends JFrame{ static final long serialVersionUID=10000;
PanelSwing panel; Controlador controlador;
public static void main(String[] args) {
// TODO Auto-generated method stub
EditorImg editor = new EditorImg();
editor.setBounds(120, 120, 800, 600);
editor.setVisible(true);
editor.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
editor.addWindowListener(new WindowAdapter() {
public void WindowCloser(WindowEvent e) {
System.exit(0);
}
}
);
}
/** * @Desc Constructor de la clase */
EditorImg() { super("Editor bsico de imagenes");
Container contentPane = getContentPane();
panel = new PanelSwing(this);
controlador = new Controlador(panel);
panel.abrir.addActionListener(controlador);
panel.guardar.addActionListener(controlador);
panel.salir.addActionListener(controlador);
panel.brillo.addActionListener(controlador);
panel.escala.addActionListener(controlador);
panel.color.addActionListener(controlador);
panel.jslBrillo.addChangeListener(controlador);
panel.jslRojo.addChangeListener(controlador);
panel.jslVerde.addChangeListener(controlador);
panel.jslAzul.addChangeListener(controlador);
contentPane.add(panel); }}
Y como vemos, lo que se hace es simplemente agregar el Controlador a la aplicacin,
instanciando un objeto de la clase Controlador, y asignando la gestin de eventos del
men principal y de los componentes JSlider a este objeto.
26

Una vez listo el paso anterior, podemos probar correr el programa y deberemos ver la
misma pantalla que en el artculo anterior, con la diferencia de que ahora ya podremos
cargar, editar y modificar las imgenes.
Por ejemplo, as es como se visualiza el cargado de las imgenes:
Aqu vemos una imagen ya cargada:
Si modificamos los colores:
O el brillo:
Y aqu como se ve en escala de grises:
Al final solo tenemos que salvar la imagen para concluir con el proceso de edicin.
Bien, el cdigo est totalmente a su disposicin y es obviamente propenso a mejoras :D,
ya que las funciones de procesamiento que aqu implementamos son algunas de las que
se consideran bsicas, pero con estos principios es posible incursionar en conceptos ms
avanzados de procesamiento de imgenes, en particular le veo mucho potencial a la clase
ProcesadorDeImagenes para seguirla desarrollando e incluir un amplio abanico de
operaciones de procesamiento de imgenes digitales, y que gracias a la abstraccin de su
diseo, pueda ser llevada a otras aplicaciones de forma transparente.
________________________________
http://www.javamexico.org/foros/comunidad/imagen_con_jfilechooser
que tal amigos alguna sugerencia para mi problema.... la idea es mostrar una imagenque
selecciono con un jfilechosser el porblema es que no lo hace , si pongo la imagen fuera
del boton si lo hae laguna sugerencia,
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.FileFilter;
import java.io.*;
public class Interfaz
{
private JFrame frame;
JPanel panel,dos;
private JScrollPane scrollpane;
private JButton pic;
private JButton audio;
private JButton salir;
public Interfaz()
{
frame = new JFrame("JAVA MULTIMEDIA ");
frame.setVisible(true);
panel=new JPanel();
panel.setLayout(null);
27

panel.setVisible(true);
frame.add(panel);
//--------------------> contenido del marco <-------------------pic=new JButton("Imagen");
pic.setBounds(10,50,100,30);
panel.add(pic);
//-------------------> fin boton pic <--------------------------audio=new JButton("Audio");
audio.setBounds(10,130,100,30);
panel.add(audio);
//-------------------> fin boton audio <--------------------------salir=new JButton("Salir");
salir.setBounds(10,200,100,30);
panel.add(salir);
/*
ImageIcon imagen = new ImageIcon("Dirk-Nowitzki1.jpg");
JLabel etiqueta = new JLabel(imagen);
etiqueta.setBounds(20,30,60,36);
panel.add(etiqueta);*/
frame.setBounds(200,300,600,360);
frame.setResizable(false);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
pic.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JFileChooser selector=new JFileChooser();
selector.setFileFilter(new FiltroJava());
int estado=selector.showOpenDialog(null);
File archivoelegido=selector.getSelectedFile();
String
ruta=archivoelegido.getPath();
if(archivoelegido.exists())
System.out.println("bien");
else
System.out.println("no bien");
if(estado==JFileChooser.APPROVE_OPTION);
{
ImageIcon imagen = new ImageIcon("ruta");
JLabel etiqueta = new JLabel(imagen);
etiqueta.setBounds(20,30,60,36);
panel.add(etiqueta);
}
}
});//boton
salir.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
28

}//constructor
}//clase
<\code>
otro
import
import
import
import

java.awt.BorderLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.io.File;

import
import
import
import
import
import
import

javax.swing.BorderFactory;
javax.swing.ImageIcon;
javax.swing.JButton;
javax.swing.JFileChooser;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;

import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;
public class Imagen implements ActionListener
{
private JFrame frame;
private JLabel labelImagen;
private JButton boton;
private JPanel panelComponentes, panelImagen;
private JFileChooser fileChooser;
public static void main(String arg[])
{
//Bloque try-catch para atrapar los errores
try
{
//Look and Feel para la aplicacion dependiendo del sistema operativo
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
e.printStackTrace();
}
//Inicia la aplicacion
new Imagen();
}
//Construtor de la clase
public Imagen()
{
//Creando frame principal y obteniendo un Contenedor y un manejador
BorderLayout
29

frame = new JFrame("Abrir imagenes");


frame.getContentPane().setLayout( new BorderLayout() );
/**Creacion de componentes*/
//Label
labelImagen = new JLabel();
//Boton
boton = new JButton("Abrir archivo");
//Seteando la propiedad actionCommand
boton.setActionCommand("abre");
//Creando paneles y aadiendolos al frame principal
panelComponentes = new JPanel();
panelComponentes.setLayout( new BorderLayout() );
panelComponentes.add(boton, BorderLayout.CENTER);
panelComponentes.setBorder( BorderFactory.createTitledBorder ("Abre la
imagen...") );
frame.add(panelComponentes, BorderLayout.NORTH);
panelImagen = new JPanel();
panelImagen.setLayout( new BorderLayout() );
panelImagen.setBorder( BorderFactory.createTitledBorder ("Visualizacion de la
imagen") );
panelImagen.add( labelImagen, BorderLayout.CENTER);
frame.add( panelImagen ,BorderLayout.CENTER );
//Estableciendo visibilidad, tamao y cierrre de la aplicacion
frame.setVisible(true);
frame.setBounds(500,200, 400, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Agregando un escuchador al boton
boton.addActionListener(this);
//Creando FileChooser
fileChooser = new JFileChooser();
//Aadiendole un filtro
FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG", "jpg",
"png");
fileChooser.setFileFilter(filter);
}
//Metodo de accion para el boton
public void actionPerformed(ActionEvent e)
{
if("abre".equals( e.getActionCommand() ) )
{
//Valor que tomara el fileChooser
int regresaValor = fileChooser.showOpenDialog(null);
//Accion del fileChooser
if(regresaValor == JFileChooser.APPROVE_OPTION)
{
30

//Crear propiedades para ser utilizadas por fileChooser


File archivoElegido = fileChooser.getSelectedFile();
//Obteniendo la direccion del archivo
String direccion = archivoElegido.getPath();
//Bloque try-catch para errores
try
{
//Obtiene la direccion del archivo y lo instancia en icon
ImageIcon icon = new ImageIcon( direccion );
//Setea el labelImagen con el archivo obtenido
labelImagen.setIcon( icon );
}
catch(Exception es)
{
JOptionPane.showMessageDialog(null, "Upss!! error abriendo la
imagen "+ es);
}
}
}
}
}

Trabajo con JFrame = http://jdeveloper.wikispaces.com/ (cmo hacer)


______________________
Calcular valores de los elementos de un arreglo = https://www.youtube.com/watch?
v=N3autujqEc4
Como Insertar una Imagen a un JLabel desde URL
En este post indicaremos como insertar una imagen como icono en un JLabel. Ademas se
insertara un scroll para que la imagen aparezca independiente del tamao.
La imagen a insertar sera tipo .jpg; se pueden utilizar imagenes con extensiones .png, jpg,
gif.
En codigo descrito a continuacion establece un JFrame, sobre el cual se insertara un
JLable, donde finalmente se pegara una imagen obtenida a traves de una URL.
JFrame>>JLabel>>imagen
Nuestro primer paso es declarar la URL:
URL url = new URL("http://www.info-centro24.com/documents/admin/uploads/classifieds/img-4530867-original.jpg");
Seguido de esto se guardara la URL sobre una variable tipo Imagen.
Image image = ImageIO.read(url);
A continuacion se crea el JLabel donde se pegara la variable "image" tipo Imagen,
estableciendola como ImageIcon();
JLabel label = new JLabel(new ImageIcon(image));
Nuestro ultimo paso es crear el Scroll y agregarlo al JLabel.
JScrollPane scroll = new JScrollPane(label);
add(scroll);
31

No olvidarse que en nuestro main tendremos que establecer el JFrame como visible,
establecer un tamano para el mismo, de la siguiente manera:
ImagenURL imagen = new ImagenURL();
imagen.setSize(400, 400);
imagen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
imagen.setVisible(true);
imagen.setLocationRelativeTo(null);
La salida de nuestro programa quedara de la siguiente manera:
El codigo se presenta a continuacion:
Data hosted with by Pastebin.com - Download Raw - See Original
package imagenurl;
import
import
import
import
import
import
import
import

java.awt.Image;
java.io.IOException;
java.net.URL;
javax.imageio.ImageIO;
javax.swing.ImageIcon;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JScrollPane;

/**
*
* @author Rafa
*/
public class ImagenURL extends JFrame{
public ImagenURL() throws IOException {
super("ImagenURL"); //establece nombre a JFrame
URL url = new URL("http://www.info-centro-24.com/documents/admin/uploads/"
+ "classifieds/img-45-30867-original.jpg");
Image image = ImageIO.read(url);
//Creal el JLabel y ingresa la imagen sobre el.
JLabel label = new JLabel(new ImageIcon(image));
//Establece las barras de desplazamiento de la imagen
JScrollPane scroll = new JScrollPane(label);
add(scroll);
}
public static void main(String[] args) throws IOException {
ImagenURL imagen = new ImagenURL();
imagen.setSize(400, 400);
imagen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
imagen.setVisible(true);
imagen.setLocationRelativeTo(null);
32

}
}
Podemos descargarnos el proyecto, click en la siguiente imagen:

http://es.slideshare.net/Votrepoete/tema-14-imgenes-en-java-por-gio = EXCELENTE Y
COMPLETO =

Tema 14 imgenes en java por gio


1. ITSON Manuel Domitsu Kono
Imgenes en Java
Una imagen es un arreglo bidimensional de colores. Cada elemento de un arreglo se llama
pixel. Una imagen es diferente de una superficie de dibujo. Los pixeles de una imagen no
coinciden necesariamente con un pixel en la superficie de dibujo. Una imagen tiene ancho
y un alto, medido en pixeles y un sistema de coordenadas que es independiente de la
superficie de dibujo. En Java 2D, una imagen se representa por las clases Image y
BufferedImage, figura 14.1.
La clase abstracta Image representa una imagen como un arreglo rectangular de pixeles.
La clase BufferedImage le permite a la aplicacin trabajar directamente con los datos de
la imagen (por ejemplo obteniendo o estableciendo el color de un pixel). Esta clase
administra directamente la imagen en memoria y provee mtodos para almacenar,
interpretar y obtener datos de los pixeles.
Figura 14.1 Clases que Representan una Imagen
2. 548 Imgenes en Java
Un objeto de tipo BufferedImage es esencialmente un objeto del tipo Image con un buffer
de datos accesible, por lo que la hace ms eficiente para trabajar que con un objeto del
tipo Image. Un objeto de tipo BufferedImage tiene un modelo de color, un objeto del tipo
33

ColorModel y un entramado de los datos de la imagen, un objeto del tipo Raster, figura
14.2.
Figura 14.2
Un objeto de Tipo Buffered Image
El objeto de tipo ColorModel provee una interpretacin de los pixeles de la imagen dentro
del espacio de color. Un espacio de color es esencialmente una coleccin de todos los
colores que pueden representarse en un dispositivo particular. Los monitores, por
ejemplo, por lo general definen su espacio de color usando el color de espacio GB. Una
impresora, por otro lado puede usar el espacio de color CMYK. Las imgenes pueden usar
una de varias subclases de ColorModel en las bibliotecas de la API de java 2D:
ComponentColorModel, en la que un pixel se representa por varios valores discretos,
tipicamente bytes, cada uno representando una componente del color, como el
componente rojo en la representacin RGB.
DirectColorModel, en la que todos los componentes de un color estn empaquetados
juntos en bits separados del mismo valor de un pixel.
IndexColorModel, en la que cada pixel es un valor representado como un ndice en una
paleta de colores. El objeto de tipo Raster almacena los datos reales de los pixeles para
una imagen en un arreglo rectangular accesado por las coordenadas x, y. Est formado de
dos partes:
Un buffer de datos, que contiene los datos crudos de la imagen.
Un modelo de muestreo, que describe como los datos estn organizados en el buffer. El
entramado, realiza las siguientes tareas:
Representa las coordenadas rectangulares de la imagen.
Mantiene la imagen en memoria.
Provee de mecanismos para crear mltiples subimgenes a partir de un solo buffer de
los datos de la imagen.
Provee de mtodos para accesar a los pixeles especficos de
una imagen.
3. La clase BufferedImage una serie de constantes para los diferentes tipos de imgenes
(modelos de colores). La tabla 14.1 describe los diferentes tipos de imgenes.
Tabla 14.1 Tipos de Imagen de la clase BufferedImage.
Tipo
Descripcin
TYPE_3BYTE_BGR
Representa una imagen con componentes RGB de 8 bits, con los
colores azul, verde y rojo almacenados en 3 bytes.
TYPE_4BYTE_ABGR Representa una imagen con componentes RGBA de 8 bits, con los
colores azul, verde y rojo almacenados en 3 bytes y un byte para el
valor de alfa. Los datos de los colores no estn premultiplicados con
el valor de alfa.
TYPE_4BYTE_ABGR Representa una imagen con componentes RGBA de 8 bits, con los
_PRE
colores azul, verde y rojo almacenados en 3 bytes y un byte para el
valor de alfa. Los datos de los colores estn premultiplicados con el
valor de alfa.
TYPE_BYTE_BINARY Representa una imagen con pixeles opacos de 1, 2 o 4 bits
empaquetados. Los valores de los pixeles representan indices a una
tabla de colores.
TYPE_BYTE_GRAY
Representa una imagen con pixeles en tonos de grises. El valor del
pixel es un tono de gris (0 a 255).
34

TYPE_BYTE_INDEXED Representa una imagen con pixeles opacos de 1 byte. Los valores de
los pixeles representan indices a una tabla de colores de 256 valores, 216 colores y el
resto de tonos de grises. TYPE_CUSTOM Tipo de imagen no reconocido. Debe ser una
imagen con formato especial. TYPE_INT_ARGB Representa una imagen con componentes
RGBA de 8 bits, con los colores azul, verde y rojo y el valor de alfa empacados en enteros.
Los datos de los colores no estn premultiplicados con el valor de alfa.
TYPE_INT_ARGB_PRE Representa una imagen con componentes RGBA de 8 bits, con los
colores azul, verde y rojo y el valor de alfa empacados en enteros. Los datos de los colores
estn premultiplicados con el valor de alfa. TYPE_INT_BGR Representa una imagen con
componentes RGBA de 8 bits, con los colores azul, verde y rojo empacados en enteros. No
hay valor de alfa. TYPE_INT_RGB Representa una imagen con componentes RGBA de 8
bits, con los colores azul, verde y empacados en enteros. No hay valor de alfa.
TYPE_USHORT_555_RGB Representa una imagen con componentes RGB de 5-5-5 bits para
los colores azul, verde y rojo. No hay valor de alfa. TYPE_USHORT_565_RGB Representa
una imagen con componentes RGB de 5-6-5 bits para los colores azul, verde y rojo. No
hay valor de alfa. TYPE_USHORT_GRAY Representa una imagen con pixeles en tonos de
grises. TYPE_INT_ARGB Representa una imagen con componentes RGBA de 8 bits, con los
colores azul, verde y rojo y el valor de alfa empacados en enteros. Los datos de los colores
no estn premultiplicados con el valor de alfa. La tabla 14.2 muestra algunos de los
mtodos de la clase BufferedImage.
Tabla 14.3 Mtodos de la clase BufferedImage.
public BufferedImage(int width, int height, int imageType)
Construye una imagen del tipo BufferedImage de alguno de los tipos de imagenes
predefinidos.
public int getWidth() public int getHeight()
Regresan el ancho y la altura de la imagen del tipo BufferedImage,
respectivamente.
public Graphics2D createGraphics()
Crea un objeto del tipo Graphics2D que puede usarse para dibujar sobre esta
imagen.
public BufferedImage getSubimage(int x, int y, int w, int h)
Regresa una subimagen de esta imagen especificada por la regin rectangular. La
imagen regresada comparte el mismo arreglo de datos que la imagen original.
Dibujado de Imgenes
Al igual que con las grficas, podemos dibujar una figura sobre cualquier componente de
swing que sea desplegable. La clase Graphics2D dispone del mtodo drawImage() cuya
sintaxis se muestra en la tabla 14.4.
Tabla 14.4 Mtodo para dibujar una Imagen BufferedImage.
public abstract void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)
//Despliega una imagen del tipo BufferedImage, que es filtrada con un filtro descrito por el
objeto op, en las coordenadas (x, y).
El siguiente cdigo muestra un mtodo que permite dibujar una imagen ...
/** * Esta clase contiene mtodos para cargar, guardar y procesar imgenes
* * @author mdomitsu */
public class Control {
... // Imagen a ser desplegada
35

private BufferedImage dbi; ...


/** * Este metodo despliega la imagen del atributo dbi del tipo BufferedImage sobre el
panel lienzo
* @param lienzo Panel sobre el que se despliega la imagen */
public void despliegaimagen(JPanel lienzo) {
// Si no hay una imagen para desplegar
if (dbi == null) {
JOptionPane.showMessageDialog(lienzo, "No hay una imagen para desplegar"); return; }
// Obtiene el tamao de la imagen
int altoImagen = dbi.getHeight();
int anchoImagen = dbi.getWidth();
// Establece el tamao del panel al tamao de la imagen
lienzo.setPreferredSize(new Dimension(altoImagen, anchoImagen));
lienzo.revalidate();
Graphics g = lienzo.getGraphics();
Graphics2D g2 = (Graphics2D) g;
// Dibuja la imagen sobre el panel
g2.drawImage(dbi, null, 1, 1); } ... }
La figura 14.3 muestra una imagen desplegada por el mtodo anterior.

36

Figura 14.3 Despliegue de una Imagen

37

Creacin de Imgenes
Podemos crear una nueva imagen (una imagen con todos los pixeles en cero) para
posteriormente dibujar sobre ella. Para ello se sigue el siguiente procedimiento:
1. Crear un objeto del tipo BufferedImage.
2. Obtener del objeto del tipo BufferedImage, un objeto del tipo Graphics2D, para dibujar
sobre la imagen.
3. Dibujar sobre la imagen usando los mtodos del objeto del tipo Graphics2D.
// El siguiente cdigo muestra un mtodo que permite crear una imagen nueva.
public class Control {
... // Imagen original
private BufferedImage obi;
/** * Este mtodo crea un objeto de tipo BufferedImage del tamao del panel del
parametro @param lienzo Panel que establece el tamao de la imagen.
public void nuevaImagen(JPanel lienzo) {
// Obtiene el tamao del panel
int altoImagen = lienzo.getHeight();
int anchoImagen = lienzo.getWidth();
// Crea una imagen del tamao del panel
obi = new BufferedImage(anchoImagen, altoImagen, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = obi.createGraphics();
// Establece el color de fondo
g2.setBackground(Color.white);
g2.clearRect(0, 0, anchoImagen, altoImagen);
// Hace que la referencia dbi apunte a obi
dbi = obi; } ... }
El siguiente cdigo dibuja sobre una imagen (nueva o existente):
/** * Este mtodo dibuja una figura sobre la imagen obi
* @param frame Ventana sobre la que se despliega el * mensaje de error */
public void dibujaEnImagen(JFrame frame) {
// Si no hay una imagen para dibujar
if (obi == null) { JOptionPane.showMessageDialog(frame, "No hay una imagen para
dibujar");
return; }
// Obtiene el contexto de graficacin de la imagen
Graphics2D g2 = obi.createGraphics();
// Establece el color de una trayectoria
g2.setPaint(Color.black);
// crea una trayectoria
38

Path2D trayectoria = new Path2D.Double(Path2D.WIND_EVEN_ODD);


trayectoria.moveTo(50, 50); trayectoria.lineTo(70, 44);
trayectoria.curveTo(100, 10, 140, 80, 160, 80);
trayectoria.lineTo(190, 40); trayectoria.lineTo(200, 56);
trayectoria.quadTo(100, 150, 70, 60);
trayectoria.closePath();
// Dibuja la trayectoria sobre la imagen
obi g2.draw(trayectoria);
// Hace que la referencia dbi apunte a obi
dbi = obi; }
Las figuras 14.4 y 14.5 muestran una figura sobre una nueva imagen y sobre una imagen
existente, dibujada por el mtodo anterior, respectivamente.

39

40

Figu
ra 14.6 Clase ImageIO La tabla 14.5 muestra los mtodos de la clase ImageIO. Tabla 14.5
Tabla 14.5 Mtodos de la Clase ImageIO. cont.
41

public static boolean write(RenderedImage im, String formatName, ImageOutputStream


output) throws IOException
Escribe la imagen del parmetro im con el formato dado por formatName al archivo,
usando el objeto del tipo ImageOutputStream.
public static boolean write(RenderedImage im, String formatName, ImageOutputStream
output) throws IOException Escribe la imagen del parmetro im con el formato dado por
formatName al archivo, usando el objeto del tipo OutputStream.
Como ejemplo de entrada / salida de imgenes se tiene un programa con una interfaz de
usuario grfica. El programa permitir leer y guardar imgenes as como procesar esas
imgenes. La opcin para leer una imagen de un archivo se muestra en la figura 14.7. Al
seleccionar esa opcin se despliega un cuadro de dilogo para seleccionar el nombre del
archivo con la imagen a leer, figuras 14.8 y 14.9. Figura 14.7
Figura 14.8 Figura 14.9 El cdigo que permite leer una imagen de un archivo es el
siguiente:
/** * Este metodo lee una imagen bmp, gif, jpg, png y la * guarda en el atributo dbi del
tipo BufferedImage
* @param frame Ventana sobre la que se despliega el cuadro * de dialogo JFileChooser */
public void leeImagen(JFrame frame) { JFileChooser fc = new JFileChooser();
// Elimina el filtro *.*
fc.setAcceptAllFileFilterUsed(false);
// Crea el filtro para las extenciones validas
FileNameExtensionFilter extFiltro = new FileNameExtensionFilter( "Images", "bmp", "gif",
"jpg", "png");
// Establece el filtro para las extenciones validas
fc.setFileFilter(extFiltro);
// Despliega el cuadro de dialogo para seleccionar la imagen a// abrir
int returnVal = fc.showOpenDialog(frame);
// Si se selecciono una imagen
if (returnVal == JFileChooser.APPROVE_OPTION) {
// Obtiene el objeto File de la imagen seleccionada
file = fc.getSelectedFile(); try {
// lee la imagen y la guarda en el atributo obi // del tipo BufferedImage
obi = ImageIO.read(file);
// Hace que la referencia dbi apunte a obi
dbi = obi; } catch (IOException e) { JOptionPane.showMessageDialog(frame, "Error al
cargar imagen"); return; } } }
La opcin para guardar una imagen de un archivo se muestra en la figura 14.7. Al
seleccionar esa opcin se despliega un cuadro de dilogo para seleccionar el nombre del
archivo en el que se guardar la imagen, figuras 14.10.
42

El cdigo que permite guardar una imagen a un archivo es el siguiente:


/** * Este metodo guarda la imagen bmp, gif, jpg, png del * atributo bi del tipo
BufferedImage en un archivo
* @param frame Ventana sobre la que se despliega el cuadro * de dialogo JFileChooser */
public void GuardaImagenComo(JFrame frame) {
File fileSel = null; JFileChooser fc = new JFileChooser();
// Elimina el filtro *.*
fc.setAcceptAllFileFilterUsed(false);
// Agrega varios filtros de imgenes
fc.addChoosableFileFilter( new FileNameExtensionFilter("Imagen
fc.addChoosableFileFilter( new FileNameExtensionFilter("Imagen
fc.addChoosableFileFilter( new FileNameExtensionFilter("Imagen
fc.addChoosableFileFilter( new FileNameExtensionFilter("Imagen

BMP", "bmp"));
GIF", "gif"));
JPG", "jpg"));
PNG", "png"));

//Establece el nombre inicial de la imagen


fc.setSelectedFile(file);
// Despliega cuadro de dialogo para obtener el nombre // del archivo en el que se va a
guardar la imagen
int returnVal = fc.showSaveDialog(frame);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String nombreExt = null;
// Obtiene el nombre del archivo seleccionado
fileSel = fc.getSelectedFile();
// Obtiene el nombre del filtro seleccionado
FileNameExtensionFilter extFiltro = (FileNameExtensionFilter) fc.getFileFilter();
// Obtiene la extension del nombre del filtro seleccionado
String ext = extFiltro.getExtensions()[0]; String path = fileSel.getPath();
// Obtiene la extension del nombre del archivo seleccionado
nombreExt = getExtension(fileSel);
// Si el nombre seleccionado no corresponde a uno de imagen
if(nombreExt
!=
null
&&
!esImageExtension(nombreExt))
{ JOptionPane.showMessageDialog(frame, "No es un archivo de imagen");
return; }
// Si no hay extension del nombre del archivo seleccionado
if (nombreExt == null) {
// Agregale la extension del nombre del filtro seleccionado
path += "." + ext; fileSel = new File(path);
nombreExt = ext; } try {
// Guarda la imagen
ImageIO.write(bi, nombreExt, fileSel); }
43

catch (IOException e) { JOptionPane.showMessageDialog(frame, "Error al guardar la


imagen");
}}}
/** * Este metodo despliega la imagen del atributo bi
* del tipo BufferedImage sobre el panel lienzo
* @param lienzo Panel sobre el que se despliega la imagen*/
public void despliegaimagen(JPanel lienzo) {
// Obtiene el tamao de la imagen
int altoImagen = bi.getHeight(); int anchoImagen = bi.getWidth();
lienzo.setPreferredSize(new Dimension(altoImagen, anchoImagen));
lienzo.revalidate(); Graphics g = lienzo.getGraphics();
Graphics2D g2 = (Graphics2D) g; g2.drawImage(bi, null, 1, 1); }
/** * Este metodo estatico borra el contenido del panel de su parametro
* un conjunto de lineas * @param lienzo Panel a borrar */
public void borra(JPanel lienzo) {
// Obtiene un objeto de tipo Graphics del panelLienzo
Graphics g = lienzo.getGraphics();
// Al invocar al metodo paint se borra su contenido
lienzo.paint(g); }
/** * Este metodo estatico obtiene la extension de un archivo
* @paramfile Objeto de tipo File de la que se obtiene * la extension * @return Extension
de un archivo */ public static String getExtension(File file) { String ext = null;
// Obtiene el nombre del archivo
String s = file.getName();
// busca el separador de la extension
int pos = s.lastIndexOf('.');
// Si hay un punto en el nombre y hay una // extension despues del punto
if (pos > 0 && pos < s.length() - 1) { ext = s.substring(pos + 1).toLowerCase();
}
return ext; }
/** * Este medodo determina si la extension del nombre de archivo
* corresponte a una imagen * @param ext Extension del nombre de archivo *
@return true si si la extension del nombre de archivo
* corresponde a una imagen, false en caso contrario */
public boolean esImageExtension(String ext) { String[] imagenesExt = {"bmp", "gif",
"jpg", "png"};
for(int i = 0; i < imagenesExt.length;i++) {
if(ext.equals(imagenesExt[i])) return true;
}
return false; } }

44

Procesamiento de Imgenes
El procesamiento de imgenes describe la forma de manipular matemticamente las
imgenes. Procesar una imagen consiste en calcular una nueva coordenada para cada
pixel de una imagen. Ese nuevo color puede depender del color actual del pixel, del color
de los pixeles vecinos, de otros parmetros o una combinacin de los anteriores. El API 2D
de Java nos permite una forma sencilla de procesar imgenes basada en la clase
BufferedImage y un conjunto de operaciones representadas en la interfaz
BufferedImageOp. Las clases que implementan esta interfaz saben como procesar una
imagen del tipo BufferedImage, llamada imagen fuente para producir una nueva imagen
llamada imagen destino. Este proceso se muestra en la figura 14.11. Figura 14.11.
Con la API 2D de Java, el procesamiento de imgenes es un procedimiento de dos pasos:
1. Instance la clase que represente la operacin a realizar.
2. Invoque a su mtodo filter() con la imagen como parmetro.
La interfaz BufferedImageOp, las clases que implementan los mtodos de la interfaz y las
clases que las soportan se muestran en la figura 14.12. Figura 14.11. Las operaciones que
realizan las clases que implementan la interfaz BufferedImageOp se muestran en la tabla
14.6. Tabla 14.6. Operaciones de Procesamiento de Imgenes Clase Operacin
ConvolveOp Convolucin: Suavizado, intensificado, deteccin de orillas. LookupOp Tabla
de bsquedas: Posterizar, binarizar. ColorConvertOp Conversin de colores: Convertir a
tonos de grises. RescaleOp Reescalar colores: Aclarar, oscurecer. AffineTransformOp
Transformar: Escalar, rotar.

45

package cargarimagen;
import
import
import
import
import
import

java.awt.Color;
java.awt.image.BufferedImage;
java.io.File;
javax.imageio.ImageIO;
javax.swing.JFileChooser;
javax.swing.filechooser.FileNameExtensionFilter;

/**
*
* @author Luis
*/
public class ProcesamientoImagen {
//Imagen actual que se ha cargado
private BufferedImage imageActual;
//Mtodo que devuelve una imagen abierta desde archivo
//Retorna un objeto BufferedImagen
public BufferedImage abrirImagen(){
//Creamos la variable que ser devuelta (la creamos como null)
BufferedImage bmp=null;
//Creamos un nuevo cuadro de dilogo para seleccionar imagen
JFileChooser selector=new JFileChooser();
//Le damos un ttulo
selector.setDialogTitle("Seleccione una imagen");
//Filtramos los tipos de archivos
FileNameExtensionFilter filtroImagen = new FileNameExtensionFilter("JPG & GIF &
BMP", "jpg", "gif", "bmp");
selector.setFileFilter(filtroImagen);
//Abrimos el cuadro de dilog
int flag=selector.showOpenDialog(null);
//Comprobamos que pulse en aceptar
if(flag==JFileChooser.APPROVE_OPTION){
try {
//Devuelve el fichero seleccionado
File imagenSeleccionada=selector.getSelectedFile();
//Asignamos a la variable bmp la imagen leida
bmp = ImageIO.read(imagenSeleccionada);
} catch (Exception e) {
}
}
//Asignamos la imagen cargada a la propiedad imageActual
imageActual=bmp;
//Retornamos el valor
return bmp;
46

}
public BufferedImage escalaGrises(){
//Variables que almacenarn los pxeles
int mediaPixel,colorSRGB;
Color colorAux;
//Recorremos la imagen pxel a pxel
for( int i = 0; i < imageActual.getWidth(); i++ ){
for( int j = 0; j < imageActual.getHeight(); j++ ){
//Almacenamos el color del pxel
colorAux=new Color(this.imageActual.getRGB(i, j));
//Calculamos la media de los tres canales (rojo, verde, azul)
mediaPixel=(int)((colorAux.getRed()+colorAux.getGreen()
+colorAux.getBlue())/3);
//Cambiamos a formato sRGB
colorSRGB=(mediaPixel << 16) | (mediaPixel << 8) | mediaPixel;
//Asignamos el nuevo valor al BufferedImage
imageActual.setRGB(i, j,colorSRGB);
}
}
//Retornamos la imagen
return imageActual;
}
}
Simplemente lo que hace esta clase es abrir una imagen (devolviendo una variable del
tipo BufferedImage) y pasar esa imagen a escala de grises (tambin devolviendo un
BufferedImage). Ahora lo que tenemos que hacer es, en nuestro formulario, hacer doble
clic sobre el botn de abrir imagen y pasar a escala de grises para gestionar el evento de
clic. Una vez realizado esto, incluimos el siguiente cdigo:
//Cdigo para cargar imagen
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
//Transformamos el BifferedImagen a ImageIcon para poder mostrarlo en el jLabel1
jLabel1.setIcon(new ImageIcon(ObjProcesamiento.abrirImagen()));
}
//Cdigo para pasar a escala de grises
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//Transformamos el BifferedImagen a ImageIcon para poder mostrarlo en el jLabel1
jLabel1.setIcon(new ImageIcon(ObjProcesamiento.escalaGrises()));
}

47

La funcin paint nos va a proporcionar el objeto g de la clase Graphics que


denominamos contexto grfico del componente (applet). Desde dicho objeto llamaremos
a las funciones miembro de la clase Graphics.
Establecer un color
El color negro es el color por defecto del contexto grfico. Para establecer otro color,
como veremos en la pgina siguiente, se utiliza la funcin setColor, y se le pasa un color
predefinido o definido por el usuario.
g.setColor(Color.cyan);
Dibujar una lnea
Para dibujar una lnea recta se llama a la funcin drawLine, le pasamos el punto inicial y el
punto final. Para dibujar una lnea diagonal desde el origen (0, 0) o esquina superior
izquierda, hasta la esquina inferior derecha, obtenemos las dimensiones del applet
mediante la funcin getSize, que devuelve un objeto de la clase Dimension. El miembro
width nos sproporciona la anchura y el miembro height la altura.
g.drawLine(0, 0, getSize().width-1, getSize().height-1);
Dibujar un rectngulo
Un rectngulo viene definido por un origen (esquina superior izquierda), su anchura y
altura. La siguiente sentencia dibuja un rectngulo cuyo origen es el punto 50, 150, que
tiene una anchura de 50, y una altura de 60. La funcin drawRect dibuja el contorno del
color seleccionado, y fillRect dibuja el rectngulo pintando su interior del color
seleccionado, en este caso de color rojo.
g.setColor(Color.red);
g.fillRect(50, 150, 50, 60);
Dibujar un arco
48

Los elipses (oval), arcos (arc), se dibujan en el interior del rectngulo circundante. Una
elipse de dibuja mediante drawOval o fillOval, con los mismos parmetros que el
rectngulo. Un arco requiere dos parmetros ms el ngulo inical y el ngulo final. Las
sentencias que vienen a continuacin, dibujan un arco en el interior del rectngulo cuyo
origen es el punto 10, 10, cuya anchura es 150, y cuya altura es 100. El ngulo inicial es 0
y el ngulo final es 270, expresado en grados.
g.setColor(Color.cyan);
g.fillArc(10, 10, 150, 100, 0, 270);
g.setColor(Color.black);
g.drawArc(10, 10, 150, 100, 0, 270);
Dibujar un polgono
Para dibujar un polgono, se requieren un array de puntos. Un polgono y una polilnea son
parecidos, el primero es una figura cerrada mientas que una polilnea es un conjunto de
segmentos. Para formar un polgono a partir de una pililnea se une el punto inicial y el
punto final. El polgono precisa de un array de abscisas x, un array de ordenadas y, y la
dimensin del array.
int[] x={100, 150, 170, 190, 200};
int[] y={120, 280, 200, 250, 60};
g.setColor(Color.blue);
g.drawPolygon(x, y, x.length);
Alternativamente, se puede usar un objeto de la clase Polygon, al cual se le aaden
puntos mediante la funcin miembro addPoint.
Polygon poligono=new Polygon();
poligono.addPoint(100, 120);
poligono.addPoint(150, 280);
poligono.addPoint(170, 200);
poligono.addPoint(190, 250);
poligono.addPoint(200, 60);
Para dibujar el polgono con su interior pintado del color seleccionado se llama a la
funcin fillPolygon y se le pasa el objeto poligono de la clase Polygon.
g.setColor(Color.yellow);
g.fillPolygon(poligono);
Veremos en el applet un polgono cuyo contorno est dibujado en azul y su interior en
amarillo.
-----------------------BufferedImage es una subclase de Image en Java, que describe una determinada imagen
rasterizada en base a modelo de color.
Podemos leer una imagen desde el disco duro y guardarla en un tipo BufferedImage con la
siguiente sentencia:
49

BufferedImage bi = ImageIO.read (C:/ruta_del_fichero/imagen.bmp);


Igualmente podramos guardar una imagen desde un tipo BufferedImage a un fichero en
disco duro de la siguiente forma (por ejemplo, en formato bmp):
ImageIO.write((RenderedImage)bi, bmp, new File(C:/ruta_del_fichero/imagen.bmp));
JPEGImageDecoder decoder =JPEGCodec.createJPEGDecoder(in);
BufferedImageimage=decoder.decodeAsBufferedImage();
g2.drawImage(image, 0, 20,this);
in.close();
}
catch(IOExceptione) {
e.printStackTrace();}catch(ImageFormatExceptione)
{
e.printStackTrace();
}
}
publicstaticvoidmain(Stringargs[]) {
Imagenes v = newImagenes();
v.setDefaultCloseOperation(EXIT_ON_CLOSE);
v.setSize(375,300);
v.setVisible(true);
nes v = newImagenes();
v.setDefaultCloseOperation(EXIT_ON_CLOSE);
v.setSize(375,300);
v.setVisible(true)

http://www.aprenderaprogramar.com/index.php?
option=com_content&view=category&id=68&Itemid=188
VISUALIZAR CLASES Y CREAR OBJETOS JAVA CON BLUEJ. INVOCAR MTODOS.
Vamos a crear varias clases y objetos en nuestro entorno de desarrollo. Para ello
repetiremos el proceso que seguimos con la clase Ejemplo pero escribiendo el siguiente
cdigo:
50

/* Ejemplo - aprenderaprogramar.com */
public class Taxi {
public static void main (String[ ] arg) {
System.out.println ("Soy un taxi");
} //Cierre del main
} //Cierre de la clase
En otra clase escribiremos:
/* Ejemplo - aprenderaprogramar.com */
public class Tranvia {
public static void main (String[ ] arg) {
System.out.println ("Soy un tranva");
} //Cierre del main
} //Cierre de la clase
La clase Ejemplo que tenamos en nuestra ventana de BlueJ la eliminaremos pulsando
sobre ella y con botn derecho elegimos Remove (tambin podemos hacerlo a travs
del men Edit -> Remove). Ahora tenemos dos clases y dos iconos de clase: Taxi y
Tranvia. Para crear objetos taxi pinchamos sobre el icono Taxi y con botn derecho
elegimos new Taxi(). Nos aparece una ventana que nos pide el nombre del objeto y
escribimos BFG_7452 (usamos guin bajo porque no se admite guin medio). Repetimos
varias veces el proceso y vamos creando distintos objetos taxi. Cada vez que creamos un
taxi nos aparece en la parte inferior izquierda un rectngulo rojo con un texto como
BFG_7452: Taxi. Este rectngulo representa un objeto taxi. El espacio en la parte inferior
izquierda de la pantalla donde se van mostrando los objetos creados de esta manera se
denomina Banco de objetos (Object Bench).
Hemos creado varios objetos taxi. Fjate que cuando solo tenemos definida la clase no
existen objetos: los objetos hay que crearlos para que existan.
Qu pueden hacer nuestros objetos taxis? Pues prcticamente nada, porque todava no
hemos escrito cdigo que nos permita hacer algo. Vamos simplemente a pedir a cada taxi
que nos diga el espacio de memoria que ocupa: para ello pulsamos sobre el icono de un
objeto taxi (por ejemplo MDE_8127) y con botn derecho seleccionamos Inherited from
Object -> String toString(). Se nos mostrar algo parecido a lo que mostramos en la
siguiente imagen:
Nos aparece: returned Taxi@105bd58 (no tiene por qu coincidir con estos dgitos).
Prueba a hacer lo mismo con otros objetos Taxi. Vers que cada objeto devuelve una
cadena Taxi@.......... distinta. Esto significa que cada objeto ocupa un espacio de memoria
distinto y a ese espacio de memoria se le denomina de esa manera un poco extraa.
Hacer esto ha sido posible porque al crear objetos en Java por defecto se dispone de
algunos mtodos comunes a cualquier objeto. Nosotros en realidad todava no hemos
definido mtodos propios para los objetos tipo Taxi.
En un programa, cada objeto de tipo Taxi podra informar de su posicin, de su tipo de
motor, etc. o ser llamado para que tome determinada posicin (coordenadas), o para
modificar el tipo de motor que tiene establecido, entre muchas otras cosas.

51

Prueba a crear objetos tranva y a consultar el identificador de su espacio de memoria.


Prueba tambin a borrar objetos del banco de objetos. Para ello pulsa sobre su icono y con
el botn derecho del ratn elige la opcin Remove.
Por ltimo, vamos a indicar un convenio que sigue la mayora de los programadores: a las
diferentes clases les pondremos nombres que comiencen por mayscula como Taxi. Por
el contrario, a los objetos les pondremos nombres que comiencen por minscula. En
nuestro caso podramos haber nombrado a los objetos como taxi_BFG_7452 para respetar
el convenio. Seguir esta norma no es obligada, pero hacerlo es recomendable para
mantener un buen estilo de programacin. Las empresas suelen mantener un manual de
estilo que sirve de gua para que todos los programadores que trabajen en un proyecto
sigan unas normas comunes.
DECLARACIN E INICIALIZACIN DE VARIABLES EN JAVA.
Vamos a ver ejemplos de uso de tipos de datos en Java. Para ello nos valdremos
primeramente de algunos tipos primitivos usados habitualmente como son int (entero),
String (cadena de caracteres), boolean (valor booleano verdadero o falso), float (decimal
simple), etc.
Aqu mostramos ejemplos de uso de tipos de datos en Java:
/* Ejemplo - aprenderaprogramar.com */
public class Ejemplo2 {
private int precio; // Las instrucciones y declaraciones finalizan con ;
private int importe_acumulado;
private String profesor;
private String aula;
private int capacidad;
private boolean funciona;
private boolean esVisible;
private float diametro;
private float peso;
private short edad;
private long masa;
private char letra1;
} //Cierre de la clase
Hemos declarado variables de tipo primitivo u objeto usando la sintaxis private
tipoElegido nombreVariable;
La palabra clave private es un indicador de en qu mbito del programa va a estar
disponible la variable. Supn que el programa es un edificio con gente trabajando y que
hay elementos en el edificio, por ejemplo una impresora, que pueden tener un uso:
individual para una persona, colectivo para un grupo de personas, colectivo para todas las
personas de una planta, colectivo para todas las personas de un departamento aunque
estn en varias plantas, o colectivo para todo el edificio. Pues bien, las variables en Java
van a quedar disponibles para su uso en ciertas partes del programa segn
especifiquemos con las palabras clave public, private, protected, package, etc. Lo
veremos ms adelante, ahora simplemente nos interesa ver cmo declarar variables y
usaremos de forma preferente la palabra clave private.

52

El hecho de declarar una variable implica que se reserva un espacio de memoria para
ella, pero no que ese espacio de memoria est ocupado aunque pueda tener un contenido
por defecto. Ten en cuenta que en Java no puedes aplicar algunas normas que rigen en
otros lenguajes, como que al declarar una variable entera sta contendr por defecto el
valor cero. En Java esta situacin puede dar lugar a errores de compilacin: una variable
entera no debemos suponer que contenga nada. Para que contenga algo debemos
asignarle un contenido. Veamos ejemplos de asignacin de contenido:
/* Ejemplo - aprenderaprogramar.com */
Precio = 42; // Entero tipo int. Un nmero sin punto decimal se interpreta normalmente
como int.
importe_acumulado = 210; // Entero tipo int
profesor = Ernesto Jurez Prez; // Tipo String
aula = A-44; // Tipo String
capacidad = 1500; // Entero tipo int
funciona = true; // Tipo boolean
esVisible = false; // Tipo boolean
diametro = 34.25f; // Tipo float. Una f o F final indica que es float.
peso = 88.77; // Tipo double. Un nmero con punto decimal se interpreta normalmente
como double.
edad = 19; // Entero tipo short
masa = 178823411L; // Entero tipo long. Una l o L final indica que es long.
letra1 = h; // Tipo char (carcter). Se escribe entre comillas simples.
Hemos planteado la declaracin de variables en primer lugar y la asignacin de contenido
en segundo lugar y por separado porque ser una forma habitual de trabajar en Java.
Esto no significa que en determinadas ocasiones no podamos declarar e inicializar
(asignar contenido) simultneamente. Por ejemplo: int edad = 19; ser una expresin
vlida y que utilizaremos en determinadas ocasiones, segn iremos viendo.
La inicializacin es un paso importante de cara a permitir un uso seguro de una variable.
Es tan importante, que en general plantearemos que se haga como paso previo a
cualquier otra cosa. Por ejemplo, si pensamos utilizar una variable denominada precio lo
primero que haremos ser establecer un valor de precio o, si no lo conocemos o lo vamos
a establecer ms adelante, estableceremos explcitamente un valor por defecto: por
ejemplo precio = - 99; precio = 0;. Utilizar una variable sin haberla inicializado es una
prctica no recomendada en Java (mal estilo de programacin) que puede dar lugar a
errores o al malfuncionamiento de los programas.
TIPOS DE DATOS (VARIABLES) EN JAVA.
Los primeros lenguajes de programacin no usaban objetos, solo variables. Una variable
podramos decir que es un espacio de la memoria del ordenador a la que asignamos un
contenido que puede ser un valor numrico (slo nmeros, con su valor de clculo) o de
tipo carcter o cadena de caracteres (valor alfanumrico que constar slo de texto o de
texto mezclado con nmeros).
Como ejemplo podemos definir una variable a que contenga 32 y esto lo escribimos
como a = 32. Posteriormente podemos cambiar el valor de a y hacer a = 78. O hacer a
equivalente al valor de otra variable b as: a = b.

53

Dado que antes hemos dicho que un objeto tambin ocupa un espacio de memoria: en
qu se parecen y en qu se diferencia un objeto de una variable? Consideraremos que las
variables son entidades elementales: un nmero, un carcter, un valor verdadero o
falso mientras que los objetos son entidades complejas que pueden estar formadas por
la agrupacin de muchas variables y mtodos. Pero ambas cosas ocupan lo mismo: un
espacio de memoria (que puede ser ms o menos grande).
En los programas en Java puede ser necesario tanto el uso de datos elementales como de
datos complejos. Por eso en Java se usa el trmino Tipos de datos para englobar a
cualquier cosa que ocupa un espacio de memoria y que puede ir tomando distintos
valores o caractersticas durante la ejecucin del programa. Es decir, en vez de hablar de
tipos de variables o de tipos de objetos, hablaremos simplemente de tipos de datos. Sin
embargo, a veces coloquialmente no se utiliza la terminologa de forma estricta: puedes
encontrarte textos o pginas web donde se habla de una variable en alusin a un objeto.
En Java diferenciamos dos tipos de datos: por un lado, los tipos primitivos, que se
corresponden con los tipos de variables en lenguajes como C y que son los datos
elementales que hemos citado. Por otro lado, los tipos objeto (que normalmente incluyen
mtodos).
Veamos los tipos de datos en Java sobre un esquema de sntesis:
Esquema de sntesis de tipos de datos en Java
Este esquema no es necesario aprendrselo de memoria en todos sus detalles, aunque s
lo iremos memorizando poco a poco a medida que lo utilicemos, por lo menos hasta tener
en nuestra cabeza los nombres de todos los tipos primitivos y envoltorio y sus
caractersticas (si son objetos o no y su rango aproximado). A continuacin mostramos el
mismo esquema en formato de tabla:
TIPOS DE DATOS EN JAVA
NOMBRE
TIPO
OCUPA
RANGO APROXIMADO
TIPOS PRIMITIVOS
(sin mtodos; no son objetos; no necesitan una invocacin para ser creados)
byte
Entero
1 byte
-128 a 127
short
Entero
2 bytes
-32768 a 32767
int
Entero
4 bytes
2*109
long
Entero
8 bytes
54

Muy grande
float
Decimal simple
4 bytes
Muy grande
double
Decimal doble
8 bytes
Muy grande
char
Carcter simple
2 bytes
--boolean
Valor true o false
1 byte
--TIPOS OBJETO
(con mtodos, necesitan una invocacin para ser creados)
Tipos de la biblioteca estndar de Java
String (cadenas de texto)
Muchos otros (p.ej. Scanner, TreeSet, ArrayList)
Tipos definidos por el programador / usuario
Cualquiera que se nos ocurra, por ejemplo Taxi, Autobus, Tranvia
arrays
Serie de elementos o formacin tipo vector o matriz. Lo consideraremos un objeto
especial que carece de mtodos.
Tipos envoltorio o wrapper (Equivalentes a los tipos primitivos pero como objetos.)
Byte
Short
Integer
Long
Float
Double
Character
Boolean
Vamos a comentar distintas cuestiones:
1. Un objeto es una cosa distinta a un tipo primitivo, aunque porten la misma
informacin. Tener siempre presente que los objetos en Java tienen un tipo de tratamiento
y los tipos primitivos, otro. Que en un momento dado contengan la misma informacin no
significa en ningn caso que sean lo mismo. Iremos viendo las diferencias entre ambos
poco a poco. De momento, recuerda que el tipo primitivo es algo elemental y el objeto
algo complejo. Supn una cesta de manzanas en la calle: algo elemental. Supn una cesta
de manzanas dentro de una nave espacial (considerando el conjunto nave + cesta): algo
complejo. La informacin que portan puede ser la misma, pero no son lo mismo.
55

2. Para qu tener esa aparente duplicidad entre tipos primitivos y tipos envoltorio? Esto
es una cuestin que atae a la concepcin del lenguaje de programacin. Tener en cuenta
una cosa: un tipo primitivo es un dato elemental y carece de mtodos, mientras que un
objeto es una entidad compleja y dispone de mtodos. Por otro lado, de acuerdo con la
especificacin de Java, es posible que necesitemos utilizar dentro de un programa un
objeto que porte como contenido un nmero entero. Desde el momento en que sea
necesario un objeto habremos de pensar en un envoltorio, por ejemplo Integer.
Inicialmente nos puede costar un poco distinguir cundo usar un tipo primitivo y cundo
un envoltorio en situaciones en las que ambos sean vlidos. Seguiremos esta regla:
usaremos por norma general tipos primitivos. Cuando para la estructura de datos o el
proceso a realizar sea necesario un objeto, usaremos un envoltorio.
3. Los nombres de tipos primitivos y envoltorio se parecen mucho. En realidad, excepto
entre int e Integer y char y Character, la diferencia se limita a que en un caso la inicial es
minscula (por ejemplo double) y en el otro es mayscula (Double). Esa similitud puede
confundirnos inicialmente, pero hemos de tener muy claro qu es cada tipo y cundo
utilizar cada tipo.
4. Una cadena de caracteres es un objeto. El tipo String en Java nos permite crear objetos
que contienen texto (palabras, frases, etc.). El texto debe ir siempre entre comillas.
Muchas veces se cree errneamente que el tipo String es un tipo primitivo por analoga
con otros lenguajes donde String funciona como una variable elemental. En Java no es as.
5. Hay distintos tipos primitivos enteros. Cul usar? Por norma general usaremos el tipo
int. Para casos en los que el entero pueda ser muy grande usaremos el tipo long. Los tipos
byte y short los usaremos cuando tengamos un mayor dominio del lenguaje.
6. Cuntos tipos de la biblioteca estndar de Java hay? Cientos o miles. Es imposible
conocerlos todos.
7. Un array es un objeto? Los arrays los consideraremos objetos especiales, los nicos
objetos en Java que carecen de mtodos.
Concepto de array: serie de elementos, cada uno de los cuales lleva asociado un ndice
numrico 0, 1, 2, 3, , n-1
QU ES UNA CLASE JAVA?
Hasta ahora hemos visto pequeos fragmentos de cdigo de ejemplo. Vamos a tratar de
escribir un cdigo ms ajustado a la realidad de la programacin Java. Para ello vamos a
definir de qu partes consta normalmente una clase Java.
Las partes habituales las identificamos en este esquema:
/* Ejemplo - aprenderaprogramar.com */
Clase Taxi { --- > EL NOMBRE DE LA CLASE
Propiedades: --- >Tambin denominadas atributos o campos (fields)
Matrcula identificativa
Distrito en el que opera
Tipo de motor diesel o gasolina
Constructor de la clase --- > Definicin de qu ocurre cuando se crea un objeto
del tipo definido por la clase
56

Operaciones disponibles: --- > Mtodos de la clase


Asignar una matrcula
Asignar un distrito
Asignar un tipo de motor
}
Esto vamos a transformarlo en cdigo usando un ejemplo. Para ello abre un nuevo
proyecto en BlueJ y crea en l una clase denominada Taxi. Escribe en ella este cdigo,
aunque no entiendas algunas partes de l.
/* Ejemplo - aprenderaprogramar.com */
//Esta clase representa un taxi. -- > Comentario general que puede incluir: cometido,
autor, versin, etc
public class Taxi { //El nombre de la clase
private String ciudad; //Ciudad de cada objeto taxi
private String matricula; //Matrcula de cada objeto taxi
private String distrito; //Distrito asignado a cada objeto taxi
private int tipoMotor; //tipo de motor asignado a cada objeto taxi. 0 = desconocido, 1 =
gasolina, 2 = diesel
//Constructor: cuando se cree un objeto taxi se ejecutar el cdigo que incluyamos en
el constructor
public Taxi () {
ciudad = Mxico D.F.;
matricula = "";
distrito = "Desconocido";
tipoMotor = 0;
} //Cierre del constructor el cdigo contina
//Mtodo para establecer la matrcula de un taxi
public void setMatricula (String valorMatricula) {
matricula = valorMatricula; //La matrcula del objeto taxi adopta el valor que
contenga valorMatricula
} //Cierre del mtodo
//Mtodo para establecer el distrito de un taxi
public void setDistrito (String valorDistrito) {
distrito = "Distrito " + valorDistrito; //El distrito del objeto taxi adopta el valor
indicado
} //Cierre del mtodo
public void setTipoMotor (int valorTipoMotor) {
tipoMotor = valorTipoMotor; //El tipoMotor del objeto taxi adopta el valor que
contenga valorTipoMotor
} //Cierre del mtodo
//Mtodo para obtener la matrcula del objeto taxi
public String getMatricula () { return matricula; } //Cierre del mtodo
//Mtodo para obtener el distrito del objeto taxi
public String getDistrito () { return distrito; } //Cierre del mtodo
//Mtodo para obtener el tipo de motor del objeto taxi
public int getTipoMotor () { return tipoMotor; } //Cierre del mtodo
} //Cierre de la clase
57

Pulsa el botn Compile y comprueba que no haya ningn error.


Repasemos lo que hemos hecho: hemos creado una clase denominada Taxi. El espacio
comprendido entre la apertura de la clase y su cierre, es decir, el espacio entre los
smbolos { y } de la clase, se denomina cuerpo de la clase.
Hemos dicho que todo objeto de tipo Taxi tendr los mismos atributos: una matrcula
(cadena de caracteres), un distrito (cadena de caracteres) y un tipo de motor (valor
entero 0, 1 o 2 representando desconocido, gasolina o diesel). Los atributos los
definiremos normalmente despus de la apertura de la clase, fuera de los constructores o
mtodos que puedan existir.
Hemos definido que cualquier objeto Taxi que se cree tendr, inicialmente, estos
atributos: como matrcula una cadena vaca; como distrito Desconocido; y como tipo de
motor 0, que es el equivalente numrico de desconocido. La sintaxis que hemos utilizado
para el constructor es public nombreDeLaClase { }
Por otro lado, hemos establecido que todo objeto Taxi podr realizar estas operaciones:
recibir un valor de matrcula y quedar con esa matrcula asignada (setMatricula); recibir
un valor de distrito y quedar con ese distrito asignado (setDistrito); recibir un valor de tipo
de motor y quedar con ese valor asignado (setTipoMotor). Devolver su matrcula cuando
se le pida (getMatricula); devolver su distrito cuando se le pida (getDistrito); devolver su
tipo de motor cuando se le pida (getTipoMotor).
Para crear objetos Taxi pinchamos sobre el icono Taxi de la clase y con botn derecho
elegimos new Taxi(). Nos aparece una ventana que nos pide el nombre del objeto. Crea 5
objetos Taxi denominados taxi1, taxi2, taxi3, taxi4 y taxi5. Cada objeto Taxi tiene tres
atributos: matricula, distrito y tipoMotor. En total tendremos 5 taxis x 3 atributos = 15
atributos.
Hemos dicho que un objeto es una instancia de una clase: por eso a los atributos que
hemos definido se les denomina variables de instancia, porque cada instancia es
portadora de esos atributos. Tambin es frecuente utilizar el trmino campos de la
clase como equivalente. Cada clase tendr sus campos especficos. Por ejemplo, si una
clase representa una moneda sus campos pueden ser pais, nombreMoneda, valor,
diametro, grosor. Si una clase representa una persona sus campos pueden ser nombre,
apellidos, dni, peso y altura.
Para qu nos sirve la clase? Para crear objetos de tipo Taxi. Por eso se dice que en Java
una clase define un tipo. Recordamos ahora la definicin de clase que habamos dado
previamente: Clase: abstraccin que define un tipo de objeto especificando qu
propiedades y operaciones disponibles va a tener.
Por qu la clase, el constructor y los mtodos se declaran public y los atributos private?
Esto lo discutiremos ms adelante. De momento, nos basta con saber que declararemos
las clases, constructores y mtodos precedidos de la palabra clave public, y que esta
palabra afecta a en qu partes del programa o por parte de quin se va a poder acceder a
ellos (igual que en el edificio con personas trabajando decamos que una impresora poda
tener un uso restringido a el personal de un departamento).

58

El orden campos --> constructor --> mtodos es obligatorio? No, pero a la hora de
programar hemos de ser metdicos y evitar el desorden. Muchos programadores
utilizamos este orden a la hora de escribir clases, as que no est mal acostumbrarnos a
seguir este orden.
Por qu en unos casos un mtodo ocupa una lnea y en otros varias lneas? Simple
cuestin de espacio. Puedes escribirlo como quieras, siempre que quede bien presentado
y legible. Hemos de tener claro que un mtodo consta de dos partes: un encabezado o
lnea inicial y un cuerpo o contenido dentro de las llaves { }. En este curso muchas veces
escribiremos mtodos en una sola lnea, o varias instrucciones en una sola lnea, para
ahorrar espacio. Sin embargo, en el trabajo como programadores el ahorro de espacio es
poco relevante frente a la claridad. Lo importante es que el cdigo sea claro.
Por qu establecemos el tipo de motor con un entero en vez de con un texto tipo String?
A veces podemos definir las variables de diferentes maneras. En este caso nos resultara
tambin vlido usar un String en vez de un int. Pero ten en cuenta una cosa: a los
ordenadores les resulta ms fcil analizar y manejar nmeros que palabras. Si tenemos
cien taxis en realidad no va a resultar demasiado importante elegir un texto o un nmero.
Pero si tenemos cien mil s puede ser relevante elegir un tipo numrico porque va a
acelerar el procesado de datos.
EJERCICIO
Considera ests desarrollando un programa Java donde necesitas trabajar con objetos de
tipo Persona. Define una clase Persona anloga a la que hemos visto para taxis, pero en
este caso considerando los siguientes atributos de clase: nombre (String), apellidos
(String), edad (int), casado (boolean), numeroDocumentoIdentidad (String). Define un
constructor y los mtodos para poder establecer y obtener los valores de los atributos.
Compila el cdigo para comprobar que no presenta errores. Para comprobar la correccin
de tu solucin puedes consultar en los foros aprenderaprogramar.com.
MTODOS PROCEDIMIENTO (VOID) Y FUNCIN (RETURN)
Volvamos sobre los objetos taxi creados y que deben aparecer en el banco de objetos en
la parte inferior izquierda de la pantalla del entorno de desarrollo. Si pulsamos con botn
derecho del ratn sobre ellos se nos despliegan los mtodos (operaciones) disponibles
para cada objeto.
Pulsa sobre el taxi1 y elige la opcin String getDistrito.
La ejecucin de un mtodo se denomina habitualmente invocacin del mtodo o
llamada al mtodo. Los mtodos disponibles los define la clase, pero se invocan sobre
cada objeto en particular. Al invocar el mtodo getDistrito() se nos abre una ventana de
BlueJ denominada Method Result donde nos indica: returned String Desconocido. Le
hemos pedido al objeto que nos diga cul es su distrito y nos devuelve Desconocido. La
razn para ello es que en el constructor de la clase incluimos una lnea de inicializacin de
distrito para todo objeto de tipo Taxi con el valor Desconocido. Si en vez de ese valor
hubisemos establecido otro, ese sera el que ahora obtendramos.
Cierra esa ventana y repite el proceso eligiendo ahora la opcin void setDistrito (String
valorDistrito). En el recuadro donde solicita el distrito escribe Oeste. No olvides incluir
59

las comillas obligadas por tratarse de un String. Seguidamente, vuelve a invocar el


mtodo getDistrito y comprueba el resultado obtenido.
Los mtodos que hemos definido en la clase Taxi podemos clasificarlos de la siguiente
manera:
a) Mtodos tipo funcin: son mtodos que nos devuelven algo. Un mtodo es tipo funcin
si comienza con un tipo (no consideramos ahora la palabra clave public). Por ejemplo
String getDistrito() comienza con el tipo String lo que significa que nos devuelve una
cadena de caracteres, mientras que int getTipoMotor() comienza con el tipo int lo que
significa que nos devuelve un entero. Tener en cuenta que un mtodo tipo funcin
devuelve solo un dato u objeto como resultado, no varios. La devolucin del resultado se
expresa con la palabra clave return seguida del dato u objeto a devolver, por ejemplo
return tipoMotor;. La sentencia return implica que termina la ejecucin del cdigo en el
mtodo y estar tpicamente en la lnea final. De existir una lnea por detrs de una
sentencia return, nunca llegara a ejecutarse (tendremos que matizar esto porque el uso
de condicionales nos permitir tener ms de un return en un mtodo). De forma genrica:
/* Ejemplo - aprenderaprogramar.com */
//Comentario descriptivo de qu hace el mtodo
public tipoValorDevuelto nombreDelMtodo (tipo parmetro1, tipo parmetro2) {
Cdigo del mtodo
return ResultadoQueDevuelveElMtodo;
}
b) Mtodos tipo procedimiento: son mtodos que realizan ciertas operaciones sin
devolver un valor u objeto concreto. Un mtodo es tipo procedimiento si comienza con la
palabra clave void (que traducido del ingls viene siendo vaco o nulo). En estos casos
podemos decir que el tipo de retorno es void. De forma genrica:
/* Ejemplo - aprenderaprogramar.com */
//Comentario descriptivo de qu hace el mtodo
public void nombreDelMtodo (tipo parmetro1, tipo parmetro2) {
Cdigo del mtodo
}
En general un mtodo con tipo de retorno void no llevar sentencia return, aunque en
Java se permite que un mtodo de este tipo incluya la sentencia return;. Si ocurre esto, la
sentencia da lugar a que el mtodo finalice en ese punto sin ejecutar ninguna lnea ms
de cdigo. Solo tiene sentido su uso asociado a que se cumplan ciertas condiciones.
Puede un mtodo ser al mismo tiempo funcin y procedimiento? Formalmente debemos
evitarlo. Podramos tratar de agrupar operaciones, pero es una situacin que trataremos
de evitar. Nos plantearemos como objetivo que todo mtodo tipo funcin se centre en
devolvernos aquello que nos interesa sin realizar otros procesos. Igualmente buscaremos
que todo procedimiento realice un proceso concreto y no varios. Cada mtodo debe
realizar una tarea concreta, especfica y bien definida. Un mtodo no debe ocuparse de
dos tareas.
EJERCICIO

60

Considera ests desarrollando un programa Java donde necesitas trabajar con objetos de
tipo DiscoMusical. Define una clase DiscoMusical anloga a la que hemos visto para taxis,
pero en este caso considerando los siguientes atributos de clase: titulo (String), autor
(String), aoEdicion (int), formato (String), digital (boolean). Define un constructor y los
mtodos para poder establecer y obtener los valores de los atributos. Compila el cdigo
para comprobar que no presenta errores. Crea un objeto y comprueba sus mtodos como
hemos hecho con los objetos Taxi. Para comprobar la correccin de tu solucin puedes
consultar en los foros aprenderaprogramar.com.
MTODOS EN JAVA CON Y SIN PARMETROS
Al igual que hicimos con distrito, contina invocando los mtodos del objeto taxi1 para
establecer sus valores de matrcula a BFG-7452 y tipo de motor a 2. Los mtodos que
hemos definido en la clase Taxi podemos clasificarlos de otra manera:
a) Mtodos que solicitan parmetros: son mtodos que nos piden algo (uno o varios datos
u objetos). Es decir, el mtodo para ejecutarse necesita que se le enve un parmetro de
un tipo concreto. Los mtodos que solicitan parmetros se identifican porque en los
parntesis finales incluyen uno o varios trminos, por ejemplo (String valorMatricula) nos
indica que el mtodo requiere un parmetro de tipo String. Fjate que en este caso el
parmetro es un objeto tipo String. En cambio la expresin (int valorTipoMotor) nos indica
que el parmetro es un tipo primitivo int. Un mtodo podra requerir varios parmetros
para lo cual se indican separados por comas. Por ejemplo public int costeVivienda (int
superficiem2, String zonaCiudad, int calidadesMedias).
b) Mtodos sin parmetros: son mtodos que no piden ningn dato u objeto para
ejecutarse. Un mtodo sin parmetros se identifica porque sus parntesis finales estn
vacos. Estos mtodos no necesitan recibir informacin para ejecutarse.
Una cuestin importante en los mtodos con parmetros es el tipo requerido. Prueba a
introducir un dato errneo. Por ejemplo, introduce el texto gasolina cuando te pida el
tipo de motor de un taxi. El resultado es que se produce un error porque el tipo recibido
no coincide con el tipo esperado. El correcto manejo de tipos es un aspecto importante en
la mayor parte de lenguajes de programacin, incluido Java, y ser algo a lo que debamos
prestar especial atencin siempre que estemos desarrollando cdigo.
Los constructores funcionan en buena medida de forma similar a los mtodos y tambin
podemos definir constructores con parmetros y constructores sin parmetros. El sentido
de que un constructor pida uno o varios parmetros es tener en cuenta esos parmetros a
la hora de crear un objeto. Abordaremos los constructores con ms detenimiento un poco
ms adelante.
MTODOS CONSULTORES (GET) Y MODIFICADORES (SET)
Continuamos con el uso de mtodos en Java. Prueba a establecer distintos valores de
matrcula, distrito y tipo de motor para los diferentes objetos Taxi. Prueba tambin a, una
vez establecidos unos valores para un objeto, volver a cambiarlos por otros valores
distintos.
Hay an otra manera de clasificar los mtodos que hemos definido para la clase Taxi:
a) Mtodos modificadores: llamamos mtodos modificadores a aquellos mtodos que dan
lugar a un cambio en el valor de uno o varios de los atributos del objeto.
61

b) Mtodos consultores u observadores: son mtodos que devuelven informacin sobre el


contenido de los atributos del objeto sin modificar los valores de estos atributos.
Cuando se crea una clase es frecuente que lo primero que se haga sea establecer
mtodos para consultar (de ah su denominacin de consultores) sus atributos y estos
mtodos suelen ir precedidos del prefijo get (getMatricula, getDistrito, etc.) por lo que
muchas veces se alude coloquialmente a ellos como mtodos get o getters.
Se suele proceder de igual forma con mtodos que permitan establecer los valores de los
atributos. Estos mtodos suelen ir precedidos del prefijo set (setMatricula, setDistrito,
etc.) por lo que muchas veces se alude coloquialmente a ellos como mtodos set o
setters. Los mtodos set son un tipo de mtodos modificadores, porque cambian el
valor de los atributos de un objeto.
Puede un mtodo ser al mismo tiempo modificador y consultor? Es posible, pero es una
situacin que trataremos de evitar. Nos plantearemos como objetivo que cada mtodo
haga una cosa especfica y no varias al mismo tiempo.
ESTADO DE UN OBJETO
Hemos comprobado que un objeto tiene unos atributos. Adems, si tenemos mtodos
disponibles para ello, podemos cambiar varias veces el valor de estos atributos. Por
ejemplo, al objeto taxi1 le podemos establecer inicialmente distrito Oeste, luego distrito
Norte, Sur, etc.
Llamamos estado de un objeto al conjunto de valores de los atributos del objeto en un
momento dado. Sobre el objeto taxi1, pulsa botn derecho y elige la opcin Inspect.
El resultado es que se nos abre una ventana que se denomina Inspector de objetos y
que refleja su estado. En este caso, nos indica que el valor de sus atributos es BFG-7452
para la matrcula del taxi, Distrito Oeste para el distrito y 2 para el tipo de motor.
Prueba a modificar el estado del objeto taxi1 utilizando alguno de sus mtodos sin cerrar
la ventana de inspeccin. Comprobars que los datos se actualizan automticamente a
medida que vamos realizando cambios. Prueba a inspeccionar el estado de los distintos
objetos Taxi que hayas creado.
PARMETROS FORMALES Y PARMETROS
Hemos visto que un mtodo (o constructor) puede requerir un parmetro, con un tipo y
nombre concretos. Por ejemplo tipo String y nombre del parmetro valorDistrito. A su vez
valorDistrito podra ir tomando distintos valores a lo largo de una ejecucin del mtodo,
por ejemplo Norte, Oeste, Sur, etc.
Vamos a definir dos conceptos relacionados con los parmetros:
a) Parmetro formal: es el nombre de un parmetro de un constructor o mtodo tal y
como se define en su cabecera, por ejemplo valorDistrito es un parmetro formal.
b) Parmetro actual: es el valor concreto que tiene un parmetro en un momento dado.
62

Prueba a escribir y compilar el siguiente cdigo:


/* Ejemplo - aprenderaprogramar.com */
//Esta clase es una prueba
public class miPrueba {
public String resultado (String dimeUnString) {
System.out.println ("dimeUnString inicialmente vale " + dimeUnString);
dimeUnString = dimeUnString + " recibido";
System.out.println ("dimeUnString ahora vale " + dimeUnString);
return "El mtodo devuelve " + dimeUnString;
}
}
Ahora crea un objeto de tipo miPrueba y ejecuta el mtodo introduciendo una cadena, por
ejemplo esperanza. El resultado ser algo similar a esto:
El parmetro formal dimeUnString es de tipo String y inicialmente toma el valor que le
hayamos pasado al constructor cuando creamos el objeto. Luego su valor actual pasa a
ser el valor pasado al constructor + recibido. Finalmente el mtodo nos devuelve una
cadena de la que forma parte el parmetro.
Conclusin interesante: los parmetros de mtodos o constructores tambin almacenan
valores que pueden ir cambiando. Por eso diremos que tambin son variables al igual que
los campos, aunque conceptualmente sean cosas distintas.
Ten en cuenta una cosa: un campo es una variable que est de forma permanente
asociada a un objeto y cuyo mbito (lugares donde podemos usarla) es toda la clase. Su
tiempo de vida es indefinido mientras exista el objeto al que est ligado. En cambio un
parmetro formal tiene un mbito limitado al mtodo o constructor y tiempo de vida
limitado al tiempo durante el cual se ejecuta el mtodo o constructor. En este sentido,
decimos que un parmetro es un tipo de variable local (solo podemos usarla dentro del
mtodo) y temporal (se crea al comenzar la ejecucin del mtodo y se destruye al
terminar su ejecucin).
Para evitar confusiones, en general trataremos de evitar modificar el contenido de un
parmetro dentro del cdigo de un mtodo.
CONCEPTO Y FILOSOFA DE MTODOS Y CLASES EN JAVA
Hemos visto la forma habitual de organizar una clase en Java. Trataremos ahora de
reflexionar sobre por qu se hacen as las cosas. Vamos a explicarlo sobre un esquema
grfico: lee el siguiente texto al mismo tiempo que miras el esquema Funcionamiento de
mtodos y clases en Java incluido a continuacin.
A un objeto le llegan muchas solicitudes, que hemos representado como personas en una
cola frente a un control de acceso. El control de acceso representa que todo lo que se
pretenda hacer est sometido a supervisin: cualquiera no puede dar rdenes y quien
puede dar rdenes no puede hacer lo que quiera. Por ejemplo, puede haber una solicitud
para establecer que la ciudad del objeto pase a ser Mrida. El control de acceso verifica
si es posible tal accin, y al no ser posible ya que no se ha definido ningn mtodo que
permita modificar el atributo ciudad, la peticin es rechazada. Puede haber otra solicitud
que pida informacin al objeto sobre qu valor tiene su atributo ciudad. El control de
63

acceso comprueba que no existe un mtodo que permita tal accin y la peticin es
rechazada.
Esquema del funcionamiento de mtodos y clases en Java
Puede haber una solicitud que pida informacin al objeto sobre su atributo distrito: es una
operacin permitida y se entrega la informacin (el estado del objeto no cambia).
Dentro del objeto el trabajo es ordenado. Hay mtodos especficamente encargados de
preparar informacin para servirla (tipo funcin). Otros mtodos se encargan de hacer
manipulaciones en el objeto.
En resumen, la clase define qu se puede hacer y qu no se puede hacer. El objeto
funciona como una entidad que trabaja de forma ordenada y especializada. Este
planteamiento difiere del que exista en los lenguajes de programacin primigenios,
donde se podan hacer modificaciones a variables desde cualquier lugar y sin control. Esto
en s no es un problema, el problema vena a posteriori cuando los programadores hacan
un mal uso de esa libertad.
En la programacin actual, se trabaja en equipos en algunos casos de cientos o miles de
personas que desarrollan cdigo por separado. Para evitar que se hagan cosas
inadecuadas, se utilizan mecanismos de control que favorecen que la programacin sea
de calidad. En Java no existe un control de acceso tal y como lo hemos representado en
nuestro esquema, pero s existen distintos mecanismos de control como la declaracin del
mbito y accesibilidad a las variables y clases (public, private, protected, etc.) y la
obligacin de uso de mtodos para realizar operaciones sobre objetos impidiendo su
manipulacin directa.
SIGNATURA DE UN MTODO. INTERFAZ O INTERFACE.
El esquema planteado en relacin a la filosofa de clases y mtodos en Java tiene otras
implicaciones. Una de ellas es que la persona que llega con una solicitud u orden no
puede ms que hacer una entrega de esa solicitud u orden, pero no puede entrar al objeto
a realizar manipulaciones o coger cosas.
Lo que pasa dentro del objeto no se ve. Este principio, denominado ocultamiento de la
informacin, se manifiesta de distintas maneras y es muy relevante en programacin
orientada a objetos. Veamos una aplicacin de este principio en relacin a lo que hemos
explicado hasta ahora. Consideremos lo siguiente:
float calcularCapacidadDeposito ()
Podemos interpretar que esto es el encabezado de un mtodo. Y podemos extraer cierta
informacin relevante: el mtodo devuelve un valor numrico tipo decimal simple, el
mtodo sirve para calcular la capacidad de un depsito, y el mtodo no requiere
parmetros. El encabezado de un mtodo se denomina signatura del mtodo e informa de
varias cosas:
a)
b)
c)
d)

Si el mtodo es tipo funcin o tipo procedimiento.


El tipo del valor devuelto, si es un mtodo tipo funcin.
El nombre del mtodo.
Los parmetros requeridos (ninguno, uno o varios) y sus tipos.
64

Veamos otro ejemplo de signatura:


float calcularCapacidadDeposito (float valorDiametro, float valorAltura)
Con esta informacin sabemos lo que hace el mtodo, pero no cmo lo hace. En general a
este tipo de informacin que nos dice qu se hace pero no cmo, lo denominamos interfaz
o interface. Esta palabra tiene distintos significados en Java que iremos viendo poco a
poco. De momento, nos quedaremos con la idea de que la signatura es una interfaz de un
mtodo, porque informa de lo que hace, pero no nos dice cmo lo hace (queda oculta su
implementacin o desarrollo). En muchas ocasiones trabajaremos conociendo slo la
signatura de mtodos y desconociendo su cdigo de desarrollo. Esto no ser problema:
mientras los procesos funcionen y estn bien programados, no nos va a hacer falta
conocer todo el cdigo.
EJERCICIO
Considera ests desarrollando un programa Java donde necesitas trabajar con objetos de
tipo DiscoMusical. Define las signaturas para mtodos dentro dicha clase e indica si
debern ser procedimientos o funciones para los siguientes objetivos planteados:
1) Obtener la duracin de una cancin expresada como un nmero decimal en minutos
(por ejemplo podra ser 3,22 minutos) recibiendo como dato el nmero de cancin dentro
del disco.
2) Pedir a un administrador de una compaa discogrfica que introduzca la duracin de
todas las canciones (dichas duraciones se almacenarn como informacin del objeto). Es
decir, el mtodo se encargar de saludar al usuario y pedirle que vaya introduciendo una
por una la duracin de las canciones.
3) Obtener la duracin del disco completo (suma de las duraciones de cada una de las
canciones).
4) Aadir una cancin al disco recibiendo como informacin para ello el ttulo de la
cancin y su duracin (se aadir como ltima cancin en el disco. Si el disco tena por
ejemplo 10 canciones, al aadirse una cancin pasar a tener 11).
Para comprobar si tu solucin es correcta puedes consultar en los foros
aprenderaprogramar.com.
VARIABLES LOCALES A UN MTODO O CONSTRUCTOR. SOBRECARGA DE NOMBRES.
Una variable que se declara y se usa dentro de un mtodo (o de un constructor) se dice
que es una variable local. Su mbito es slo el mtodo o constructor y su tiempo de vida
es solo el del mtodo, es decir, son variables temporales que se crean cuando comienza a
ejecutarse el mtodo y se destruyen cuando termina de ejecutarse.
Escribe y compila el siguiente cdigo:
/* Ejemplo - aprenderaprogramar.com */
public class Estudiante { //El nombre de la clase
private String nombre; //Campo de los objetos Estudiante
//Constructor: cuando se cree un objeto Estudiante se ejecutar el cdigo que
incluyamos en el constructor
public Estudiante () {
65

nombre = "Pepe";
} //Cierre del constructor
//Mtodo que devuelve true si el nombre del objeto tipo Estudiante es Pepe
public boolean esPepe() {
boolean seLlamaPepe = false;
if (nombre == "Pepe") { seLlamaPepe = true; }
return seLlamaPepe;
} //Cierre del mtodo
} //Cierre de la clase
La variable seLlamaPepe es una variable local booleana. Es habitual inicializar las
variables locales cuando se las declara, pero no es estrictamente necesario. S es
obligatorio inicializar las variables en algn momento ya que no se debe considerar que
tengan un valor por defecto. Crea un objeto de tipo Estudiante pulsando sobre el icono de
la clase con botn derecho y eligiendo la opcin new Estudiante(). Sobre el objeto que
aparecer en el banco de objetos, invoca el mtodo esPepe().
Ahora crea otro mtodo y trata de establecer en l la variable seLlamaPepe con valor
true. El compilador lanzar un mensaje de error del tipo cannot find symbol variable
seLlamaPepe. Por qu podemos usar la variable nombre en cualquier mtodo mientras
que la variable seLlamaPepe slo dentro del mtodo esPepe()? Como hemos dicho, el
mbito de una variable declarada en un mtodo es solo ese mtodo. El resto de mtodos
no conocen la variable. En cambio, un campo de la clase tiene como mbito toda la clase
y lo podemos usar en cualquier lugar del cdigo de la clase. Hay algunas conclusiones
interesantes:
1) Podemos usar el mismo nombre de variable local en muchos mtodos, puesto que no
van a interferir entre ellas.
2) Una declaracin de campo siempre la hacemos precedida de public o private. En las
variables locales, estas palabras clave no se usan debido a su carcter temporal.
3) En los mtodos tipo funcin con frecuencia en la sentencia return se devuelve como
resultado el valor de una variable local que ha sido objeto de clculo en el mtodo. Tener
en cuenta que no se devuelve la variable en s (que en realidad desaparece cuando
termina el mtodo), sino su valor o contenido.
Puede un constructor tener variables locales? S. Un constructor son una serie de
instrucciones. A veces muy sencillas, pero otras veces pueden requerir clculos o
procesos complejos. Por tanto, podemos usar variables locales dentro de ellos
declarndolas y usndolas como si se tratara de un mtodo. No tenemos restricciones en
cuanto al cdigo que se puede incluir en un constructor.
Puede una variable local ser tipo objeto? S. Hemos dicho que las clases definen tipos.
Por ejemplo podramos tener una variable local miTaxi1 declarada como Taxi miTaxi1;.
Qu ocurre si una variable local tiene el mismo nombre que un campo? Esta situacin se
dara si tenemos un campo declarado por ejemplo como String ciudad; y luego
declaramos dentro de un mtodo una variable de ese mismo tipo u otro distinto con el
mismo nombre, por ejemplo boolean ciudad = false;. En este caso decimos que existe
sobrecarga de nombres. Podemos tener problemas si no manejamos esta situacin
adecuadamente. Cuando empleemos en el cdigo el nombre de la variable el compilador
66

no es capaz de adivinar nuestro pensamiento para saber si nos referimos al campo de la


clase o a la variable local del mtodo. Este conflicto Java lo resuelve aplicando la regla de
prevalencia del mbito ms local. Es decir, si escribimos un nombre de variable Java usa
la variable ms local disponible. Java tiene prevista la solucin para poder usar
simultneamente campos y variables locales con el mismo nombre, mediante el uso de la
palabra clave this. Esto lo explicaremos ms adelante. Reflexionemos ahora sobre los
tipos o formas de variables que hemos visto hasta el momento. Se resumen en el
siguiente esquema:
EJERCICIO
Considera ests desarrollando un programa Java donde necesitas trabajar con objetos de
tipo Motor (que representa el motor de una bomba para mover fluidos). Define una clase
Motor considerando los siguientes atributos de clase: tipoBomba (int), tipoFluido (String),
combustible (String). Define un constructor asignando unos valores de defecto a los
atributos y los mtodos para poder establecer y obtener los valores de los atributos. Crea
un mtodo tipo funcin que devuelva un booleano (true o false) denominado
dimeSiMotorEsParaAgua() donde se cree una variable local booleana motorEsParaAgua de
forma que si el tipo de motor tiene valor 1 tomar valor true y si no lo es tomar valor
false. El mtodo debe devolver la la variable local booleana motorEsParaAgua.
Compila el cdigo para comprobar que no presenta errores, crea un objeto, usa sus
mtodos y comprueba que se obtienen resultados correctos. Para comprobar si es
correcta tu solucin puedes consultar en los foros aprenderaprogramar.com.
CMO CREAR CONSTRUCTORES EN JAVA. EJERCICIOS EJEMPLOS RESUELTOS.
Los constructores de una clase son fragmentos de cdigo que sirven para inicializar un
objeto a un estado determinado. Una clase puede carecer de constructor, pero esto no es
lo ms habitual. Normalmente todas nuestras clases llevarn constructor. En un
constructor es frecuente usar un esquema de este tipo:
/* Ejemplo - aprenderaprogramar.com */
public MismoNombreQueLaClase (tipo parmetro1, tipo parmetro2 , tipo parmetro n )
{
campo1 = valor o parmetro;
campo2 = valor o parmetro;
.
.
.
campo n = valor o parmetro;
}
Los constructores tienen el mismo nombre que la clase en la que son definidos y nunca
tienen tipo de retorno, ni especificado ni void. Tenemos aqu un aspecto que nos permite
diferenciar constructores de mtodos: un constructor nunca tiene tipo de retorno mientras
que un mtodo siempre lo tiene. Es recomendable que en un constructor se inicialicen
todos los atributos de la clase aunque su valor vaya a ser nulo o vaco. Si un atributo se
quiere inicializar a cero (valores numricos) siempre lo declararemos especficamente:
nombreAtributo = 0;. Si un atributo se quiere inicializar a contenido nulo (atributos que
son objetos) siempre lo declararemos especficamente: nombreAtributo = null;. Si un
atributo tipo texto se quiere inicializar vaco siempre lo declararemos especficamente:
67

nombreAtributo = ;. El motivo para actuar de esta manera es que declarando los


atributos como nulos o vacos, dejamos claro que esa es nuestra decisin como
programadores. Si dejamos de incluir uno o varios campos en el constructor puede quedar
la duda de si hemos olvidado inicializar ese campo o inducir a pensar que trabajamos con
malas prcticas de programacin.
La inicializacin de campos y variables es un proceso muy importante. Su mala definicin
es fuente de problemas en el desarrollo de programas. Como regla de buena
programacin, cuando crees campos o variables, procede de forma inmediata a definir su
inicializacin.
Un constructor puede:
a) Carecer de parmetros: que no sea necesario pasarle un parmetro o varios al objeto
para inicializarse. Un constructor sin parmetros se denomina constructor general.
b) Carecer de contenido. Por ejemplo, public Taxi () { } podra ser un constructor, vaco.
En general un constructor no estar vaco, pero en algunos casos particulares puede
estarlo. Si el constructor carece de contenido los campos se inicializan con valor nulo o, si
son tipos definidos en otra clase, como se haya definido en el constructor de la otra clase.
Excepto en casos controlados, evitaremos que existan constructores vacos.
Si un constructor tiene parmetros, el funcionamiento es anlogo al que ya hemos visto
para mtodos. Cuando vayamos a crear el objeto con BlueJ, se nos pedir adems del
nombre que va a tener el objeto, el valor o contenido de los parmetros requeridos. Un
parmetro con frecuencia sirve para inicializar el objeto como hemos visto, y en ese caso
el objeto tendr el valor pasado como parmetro como atributo para siempre, a no ser
que lo cambiemos por otra va como puede ser un mtodo modificador del atributo. No
obstante, en algunos casos los parmetros que recibe un constructor no se incorporarn
directamente como atributos del objeto sino que servirn para realizar operaciones de
diversa ndole. Escribe y compila el siguiente cdigo:
/* Ejemplo - aprenderaprogramar.com */
public class Taxi { //El nombre de la clase
private String ciudad; //Ciudad de cada objeto taxi
private String matricula; //Matrcula de cada objeto taxi
private String distrito; //Distrito asignado a cada objeto taxi
private int tipoMotor; //Tipo de motor asignado a cada objeto taxi. 0 = desconocido, 1 =
gasolina, 2 = diesel
//Constructor: cuando se cree un objeto taxi se ejecutar el cdigo que incluyamos en
el constructor
public Taxi (String valorMatricula, String valorDistrito, int valorTipoMotor) {
ciudad = "Mxico D.F.";
matricula = valorMatricula;
distrito = valorDistrito;
tipoMotor = valorTipoMotor;
} //Cierre del constructor
//Mtodo para obtener la matrcula del objeto taxi
public String getMatricula () { return matricula; } //Cierre del mtodo
68

//Mtodo para obtener el distrito del objeto taxi


public String getDistrito () { return distrito; } //Cierre del mtodo
//Mtodo para obtener el tipo de motor del objeto taxi
public int getTipoMotor () { return tipoMotor; } //Cierre del mtodo
} //Cierre de la clase
Este cdigo es similar al que vimos en epgrafes anteriores. La diferencia radica en que
ahora en vez de tener un constructor que establece una forma fija de inicializar el objeto,
la inicializacin depende de los parmetros que le lleguen al constructor. Adems, hemos
eliminado los mtodos para establecer el valor de los atributos. Ahora stos solo se
pueden consultar mediante los mtodos get. Pulsa con botn derecho sobre el icono de la
clase y vers como la opcin new Taxi incluye ahora los parmetros dentro de los
parntesis. Escoge esta opcin y establece unos valores como matrcula BFG-7452,
distrito Oeste y tipo de motor 2. Luego, con el botn derecho sobre el icono del objeto,
elige la opcin Inspect para ver su estado.
Que un constructor lleve o no parmetros y cules tendremos que elegirlo para cada clase
que programemos. En nuestro ejemplo hemos decidido que aunque la clase tiene cuatro
campos, el constructor lleve solo tres parmetros e inicializar el campo restante con un
valor fijo. Un constructor con parmetros es adecuado si tiene poco sentido inicializar los
objetos vacos o siempre con el mismo contenido para uno o varios campos. No obstante,
siempre hay posibilidad de darle contenido a los atributos a posteriori si incluimos
mtodos setters. El hacerlo de una forma u otra depender del caso concreto al que nos
enfrentemos.
El esquema que hemos visto supone que en general vamos a realizar una declaracin de
campo en cabecera de la clase, por ejemplo String ciudad;, y posteriormente inicializar
esa variable en el constructor, por ejemplo ciudad = Mxico D.F.;. Sera posible hacer
una declaracin en cabecera de clase del tipo String ciudad = Mxico D.F.;? La
respuesta es que s. El campo quedara inicializado en cabecera, pero esto en general
debe ser considerado una mala prctica de programacin y contraproducente dentro de la
lgica de la programacin orientada a objetos. Por tanto de momento trataremos de evitar
incluir cdigo de ese tipo en nuestras clases y procederemos siempre a inicializar en los
constructores.
EJERCICIO
Define una clase Bombero considerando los siguientes atributos de clase: nombre
(String), apellidos (String), edad (int), casado (boolean), especialista (boolean). Define un
constructor que reciba los parmetros necesarios para la inicializacin y los mtodos para
poder establecer y obtener los valores de los atributos. Compila el cdigo para comprobar
que no presenta errores, crea un objeto y comprueba que se inicializa correctamente
consultando el valor de sus atributos despus de haber creado el objeto. Para comprobar
si es correcta tu solucin puedes consultar en los foros aprenderaprogramar.com.
CLASES QUE UTILIZAN OBJETOS. RELACIN DE USO ENTRE CLASES. DIAGRAMAS DE
CLASES.
Hemos visto hasta ahora clases que definen tipos donde los campos son variables de tipo
primitivo o String. Analicemos ahora la posibilidad de crear clases donde los atributos
sean tipos que hayamos definido en otras clases.
69

Consideraremos que partimos de las clases Taxi y Persona ya escritas y compilando


correctamente conforme a los ejemplos vistos en epgrafes anteriores.
clases java
Escribe y compila el siguiente cdigo:
/* Ejemplo - aprenderaprogramar.com */
//Ejemplo de clase que utiliza tipos definidos en otras clases (usa otras clases)
public class TaxiCond {
private Taxi vehiculoTaxi;
private Persona conductorTaxi;
//Constructor
public TaxiCond () {
vehiculoTaxi = new Taxi (); //Creamos un objeto Taxi con el constructor general de
Taxi
conductorTaxi = new Persona (); //Creamos un objeto Persona con el constructor
general de Persona
}
public void setMatricula (String valorMatricula)
{ vehiculoTaxi.setMatricula(valorMatricula); }
//Mtodo que devuelve la informacin sobre el objeto TaxiCond
public String getDatosTaxiCond () {
String matricula = vehiculoTaxi.getMatricula();
String distrito = vehiculoTaxi.getDistrito();
int tipoMotor = vehiculoTaxi.getTipoMotor();
String cadenaTipoMotor = "";
if (tipoMotor ==0) { cadenaTipoMotor = "Desconocido"; }
else if (tipoMotor == 1) { cadenaTipoMotor = "Gasolina"; }
else if (tipoMotor == 2) { cadenaTipoMotor = "Diesel"; }
String datosTaxiCond = "El objeto TaxiCond presenta estos datos. Matrcula: " +
matricula +
" Distrito: " + distrito + " Tipo de motor: " + cadenaTipoMotor;
System.out.println (datosTaxiCond);
return datosTaxiCond;
} //Cierre del mtodo
} //Cierre de la clase
Analicemos ahora lo que hace este cdigo. Creamos una clase denominada TaxiCond (que
podemos interpretar como taxi con conductor). Los objetos del tipo TaxiCond decimos
que van a constar de dos campos: un objeto Taxi y un objeto Persona. Fjate que estamos
utilizando el nombre de otra clase como si fuera el tipo de una variable normal y
corriente. Esto es posible porque las clases definen tipos. Desde el momento en que
nuestra clase utiliza tipos definidos por otras clases decimos que se establece una
relacin de uso: TaxiCond usa a Taxi y a Persona. El constructor de TaxiCond inicializa los
objetos de este tipo para que consten de un objeto Taxi creado con el constructor por
defecto y de una Persona creada con el constructor por defecto.
Para los objetos de tipo TaxiCond hemos definido dos mtodos (podramos haber definido
muchos ms) que son: el mtodo modificador y con parmetros setMatricula(String
valorMatricula) y el mtodo observador y sin parmetros getDatosTaxiCond(). Un aspecto
muy importante del cdigo es que desde el momento en que usamos objetos en una
clase, podemos acceder a los mtodos pblicos propios de esos objetos cuyo cdigo se
70

encontrar en otra clase. Por ejemplo la invocacin


vehiculoTaxi.setMatricula(valorMatricula); llama un mtodo propio de los objetos Taxi que
se encuentra definido en otra clase. Es decir, todo objeto puede llamar a sus mtodos
pblicos independientemente de dnde se encuentre.
Una vez compilado el cdigo, en el diagrama de clases se nos muestran unas flechas
discontinuas que relacionan la clase Taxicond con las clases Taxi y Persona. Estas flechas
discontinuas lo que indican es que hay una relacin de uso entre las clases. En algunas
circunstancias BlueJ puede mantener errneamente indicadores de relacin que no son
ciertos. En estos casos, las flechas pueden eliminarse seleccionndolas y con botn
derecho eligiendo la opcin Remove. Tambin pueden crearse eligiendo el botn ----> en
la parte superior izquierda de la pantalla y a continuacin pulsando primero el icono de la
clase que usa y luego el icono de la clase que es usada.
Crea un objeto de tipo TaxiCond pulsando sobre el icono de la clase y con botn derecho
eligiendo new TaxiCond(). A continuacin con botn derecho sobre el objeto elige la
opcin Inspect. La ventana que se nos muestra nos indica que el objeto consta de dos
campos, pero en el recuadro correspondiente al valor de dichos campos en vez de un
valor nos aparece una flecha curvada. Esta flecha lo que nos indica el que el campo no
contiene un valor simple (como un entero) sino un objeto. La flecha simboliza una
referencia al objeto, ya que el objeto no se puede representar directamente al ser una
entidad compleja.

Pulsa sobre la flecha de referencia de cada uno de los campos y luego sobre el botn
Inspect de la ventana. Se te abrirn otras dos ventanas donde puedes observar los
valores de los campos de cada uno de los objetos que forman el objeto TaxiCond. Pero ten
en cuenta que un objeto siempre podra tener como campo otro objeto, es decir,
podramos seguir observando flechas una y otra vez al ir inspeccionando objetos y esto
sera una situacin normal. Estamos trabajando con programacin orientada a objetos,
por tanto que aparezcan objetos por todos lados ser normal.
La relacin de uso entre clases es una de los tipos de relacin ms habituales en
programacin orientada a objetos. Las variables de instancia de un objeto pueden ser
tanto de tipo primitivo como tipo objeto. Recordar que la variable que define un objeto no
contiene al objeto en s mismo, sino una referencia al espacio de memoria donde se
encuentra. Dado que un objeto es una entidad compleja simblicamente se representa
con una lnea que comienza en un punto y termina en una punta de flecha. Un objeto
puede crearse e invocar sus mtodos pblicos desde distintas clases y decimos que esto
establece una relacin de uso entre clases. Por tanto, el cdigo fuente de una clase puede
ser usado desde otras clases.
Un esquema donde se representan las clases y las relaciones que existen entre ellas se
denomina diagrama de clases y nos sirve para comprender la estructura de los
programas. Se dice que el diagrama de clases constituye una vista esttica del programa,
porque es un esquema fijo de relaciones dentro del programa. Sin embargo, el que exista
una relacin entre clases no significa que en un momento dado vaya a existir un objeto
que materialice esa relacin entre clases. Es posible que el programa comience y que
71

pase un tiempo antes de que se cree un objeto que refleje la relacin entre clases. Si
representramos los objetos existentes en un momento dado y las relaciones entre ellos
tendramos una vista dinmica del programa. El inconveniente de las vistas dinmicas es
que los objetos se crean, destruyen o cambian sus relaciones continuamente, por lo que
representarlas resulta costoso. Por este motivo, no utilizaremos las vistas dinmicas. Sin
embargo, s usaremos con frecuencia los diagramas de clases para comprender la
estructura de nuestro cdigo.
Nos queda una aclaracin por realizar: Por qu si los tipo String son objetos BlueJ nos
informa directamente de su contenido en vez de mostrar una flecha? La razn para ello
estriba en que el tipo String es un objeto un tanto especial, ya que su contenido es
relativamente simple comparado con el de otros objetos. Para facilitar el trabajo BlueJ nos
informa directamente de su contenido, pero no podemos olvidar que un String es un
objeto y esto tiene una relevancia notable como veremos ms adelante.
Para completar la comprensin de la relacin de uso entre clases, utiliza los mtodos
disponibles para el objeto TaxiCond que has creado: establece distintos valores de
matrcula con el mtodo setMatricula y visualiza los datos del objeto con el mtodo
getDatosTaxiCond. Crea adems nuevos mtodos que te permitan establecer el distrito y
el tipo de motor de los objetos TaxiCond. Te planteamos otra reflexin: al igual que hemos
definido un tipo TaxiCond que tiene dos objetos como campos, podemos definir tipos que
tengan cinco, diez, quince o veinte objetos como campos. Por ejemplo, un objeto Casa
podra definirse con estos campos:
private
private
private
private
private
private
private
private

Salon salonCasa;
Cocina cocinaCasa;
Bao bao1Casa;
Bao bao2Casa;
Jardin jardinCasa;
Dormitorio dormitorio1Casa;
Dormitorio dormitorio2Casa;
Dormitorio dormitorio3Casa;

Ten en cuenta que dentro de un objeto puedes tener n objetos de otro tipo. En este
ejemplo, dentro de un objeto Casa tenemos dos objetos de tipo Bao y tres objetos de
tipo Dormitorio. Todos los objetos Dormitorio van a tener los mismos atributos y mtodos,
pero cada objeto tendr su propio estado en cada momento.
EJERCICIO
Define tres clases: Casa, SalonCasa y CocinaCasa. La clase SalonCasa debe tener como
atributos numeroDeTelevisores (int) y tipoSalon (String) y disponer de un constructor que
los inicialice a 0 y desconocido. La clase CocinaCasa debe tener como atributos
esIndependiente (boolean) y numeroDeFuegos (int) y un constructor que los inicialice a
false y 0. La clase Casa tendr los siguientes atributos de clase: superficie (double),
direccion (String), salonCasa (tipo SalonCasa) y cocina (tipo CocinaCasa). Define un
constructor para la clase Casa que establezca a unos valores de defecto los atributos
simples y que cree nuevos objetos si se trata de atributos objeto. Compila el cdigo para
72

comprobar que no presenta errores, crea un objeto de tipo Casa. Comprueba que se
inicializan correctamente consultando el valor de sus atributos despus de haber creado
los objetos. Para comprobar si es correcta tu solucin puedes consultar en los foros
aprenderaprogramar.com.

LA SENTENCIA NEW COMO INVOCACIN DE UN CONSTRUCTOR EN JAVA


En el ejemplo anterior hemos visto cmo usar el entorno de desarrollo BlueJ para crear objetos en Java.
La forma de creacin de objetos ha sido a travs del IDE y con una visualizacin grfica Si
escribiramos el cdigo correspondiente a lo que hemos hecho en el ejemplo anterior usando los iconos
de BlueJ podra ser algo as:

/* Ejemplo - aprenderaprogramar.com */
Taxi taxi1 = new Taxi(); //Creacin de un objeto tipo Taxi
Persona persona1 = new Persona(); //Creacin de un objeto tipo Persona
TaxiCond taxiCond1 = new TaxiCond (taxi1, persona1); /*Creacin de un objeto tipo TaxiCond
pasando como parmetros otros objetos creados previamente*/

Tener en cuenta que cuando incluimos como atributo de una clase un objeto usando una sintaxis del
tipo: private NombreDeLaOtraClase nombreDelObjeto;, con esta declaracin estamos creando la
variable apuntadora (referencia) al objeto, pero el objeto en s mismo todava no se ha creado. La
creacin del objeto en cdigo se indica usando esta sintaxis:
nombreDelObjeto = new NombreDeLaOtraClase (parmetros requeridos por el constructor de la otra
clase si los hubiera);
Recordar que la variable nombreDelObjeto contiene una referencia (puntero) al objeto, no el objeto en
s mismo. La instruccin new implica que se producen dos acciones:
a)

Creacin de un objeto de un tipo definido por una clase.

b)

Ejecucin del constructor asociado.

Si una clase define varios constructores, el constructor invocado por la sentencia new es el que coincide
en nmero y tipo de parmetros con los utilizados en la sentencia new. Por ejemplo: taxi1 = new Taxi();
invoca al constructor general, mientras que taxi1 = new Taxi (BFG-7432) invoca al constructor que
requiere un String como parmetro. new Taxi (BFG-7432, Oeste) invocara al constructor que
requiere dos String como parmetros. new Taxi (BFG-7432, Oeste, 2) invocara al constructor que
requiere dos String y un entero como parmetros, etc. No puede haber dos constructores que
requieran el mismo nmero y tipo de parmetros (por ejemplo dos constructores que requieran un
String) porque eso generara una ambigedad que dara lugar a un error de compilacin.
73

QU ES Y PARA QU SIRVE EL API DE JAVA?


Hasta ahora hemos visto ejemplos donde utilizbamos la clase System (por ejemplo en la invocacin
System.out.println) o la clase String (que es la clase gracias a la que podemos usar los objetos String).
De dnde salen estas clases si nosotros no las hemos programado como la clase Taxi o la clase
Exponenciador?
La respuesta est en que al instalar Java (el paquete JDK) en nuestro ordenador, adems del
compilador y la mquina virtual de Java se instalan bastantes ms elementos. Entre ellos, una cantidad
muy importante de clases que ofrece la multinacional desarrolladora de Java y que estn a disposicin
de todos los programadores listas para ser usadas. Estas clases junto a otros elementos forman lo que se
denomina API (Application Programming Interface) de Java.
La mayora de los lenguajes orientados a objetos ofrecen a los programadores bibliotecas de clases que
facilitan el trabajo con el lenguaje.
Los siguientes esquemas, parte de la documentacin de Java, nos dan una idea de cmo funciona el
sistema Java y de qu se instala cuando instalamos Java (el paquete JDK) en nuestro ordenador.

Este esquema no nos interesa analizarlo en profundidad. Lo nico que queremos mostrar es que cuando
instalamos Java en nuestro ordenador instalamos mltiples herramientas, entre ellas una serie de
libreras (paquetes) a cuyo conjunto solemos referirnos como biblioteca estndar de Java. Las
74

libreras contienen cdigo Java listo para ser usado por nosotros. Ese es el motivo de que podamos usar
clases como System o String sin necesidad de programarlas.
Dnde se encuentra el cdigo de estas libreras? En los archivos que se instalan en nuestro
ordenador cuando instalamos Java.
Podemos acceder al cdigo de estas libreras? La respuesta es que no. Las biblioteca estndar de
Java se facilita como cdigo cerrado, es decir, como cdigo mquina. No podemos acceder al cdigo
fuente. Esto tiene su lgica porque si cada persona accediera al cdigo fuente de los elementos
esenciales de Java y los modificara, no habra compatibilidad ni homogeneidad en la forma de escribir
programas Java.
Para qu nos sirve la biblioteca si no podemos acceder a su cdigo fuente? Aunque no podamos
acceder al cdigo fuente, s podemos crear objetos de los tipos definidos en la librera e invocar sus
mtodos. Para ello lo nico que hemos de hacer es conocer las clases y la signatura de los mtodos, y
esto lo tenemos disponible en la documentacin de Java accesible para todos los programadores a travs
de internet o cds de libros y revistas especializadas. Te acuerdas cuando hablamos de la definicin de
signatura e interfaz? Esto es ahora plenamente aplicable con el API de Java: tenemos disponible
informacin de las clases, de qu hacen y cmo podemos trabajar con ellas, aunque no dispongamos del
cdigo fuente.
CONCEPCIN DE
MODULARIZACIN

PROGRAMAS

EN

JAVA

MEDIANTE

ABSTRACCIN

Los programas informticos suelen ser muy complejos como para abordarlos en su conjunto. Por ello
han de usarse tcnicas para dividir el problema (estrategia divide y vencers) que nos permitan crear
programas complejos a partir de partes ms simples. Hablamos de abstraccin para referirnos a partes
complejas ensambladas a partir de partes simples.
Supongamos que necesitamos un programa informtico para la gestin de un hotel. El programa habr
que dividirlo para construirlo y ensamblarlo para su puesta en funcionamiento:

75

El programador que se encarga de una parte del software usa otras partes de software desarrolladas por
otros sin analizar sus detalles (se abstrae de los detalles).
Hablamos de modularizacin del software en alusin a dividir un programa en partes independientes
que pueden ser construidas y probadas por separado para luego ensamblarlas formando un todo. De
acuerdo con esta terminologa abstraer sera subir de nivel o ensamblar, mientras que modularizar
sera bajar de nivel o despiezar.
En programacin orientada a objetos la abstraccin la materializamos construyendo objetos que usan o
son combinacin de otros objetos ms simples. De este modo podemos construir objetos de gran
complejidad sin necesidad de crear un cdigo largo y complejo.
UN EJEMPLO DE CDIGO JAVA BSICO. CREAR CLASES CON CAMPOS, CONSTRUCTOR Y
MTODOS
Para familiarizarnos con el cdigo Java escribe y estudia el cdigo que mostramos a continuacin,
correspondiente a dos clases. Todos los elementos que forman parte de l ya los hemos estudiado
excepto la llamada this (0, 0, ). La palabra clave this tiene distintos usos en Java y en general
podramos interpretarla como este objeto.
La invocacin this , o this (parmetros) supone una invocacin al constructor que coincida con los
parmetros que se pasan para que se ejecute. Al igual que existen formas de invocar a mtodos, existen
formas de invocar a constructores, y sta es una de ellas.
El cdigo de la primera clase sera el siguiente:
/* Ejemplo - aprenderaprogramar.com */
/* Esta clase representa un depsito cilndrico donde se almacena aceite */

public class Deposito {


//Campos de la clase
private float diametro;
private float altura;
private String idDeposito;
//Constructor sin parmetros auxiliar
public Deposito () { //Lo que hace es llamar al constructor con parmetros pasndole valores vacos
this(0,0,"");
76

} //Cierre del constructor

//Constructor de la clase que pide los parmetros necesarios


public Deposito (float valor_diametro, float valor_altura, String valor_idDeposito) {
if (valor_diametro > 0 && valor_altura > 0) {
diametro = valor_diametro;
altura = valor_altura;
idDeposito = valor_idDeposito;
} else {
diametro = 10;
altura = 5;
idDeposito = "000";
System.out.println ("Creado depsito con valores por defecto diametro 10 metros altura 5 metros
id 000" );
} } //Cierre del constructor

public void setValoresDeposito (String valor_idDeposito, float valor_diametro, float valor_altura) {


idDeposito = valor_idDeposito;
diametro = valor_diametro;
altura = valor_altura;
if (idDeposito !="" && valor_diametro > 0 && valor_altura > 0) {
} else {
System.out.println ("Valores no admisibles. No se han establecido valores para el depsito");
//Deposito (0.0f, 0.0f, ""); Esto no es posible. Un constructor no es un mtodo y por tanto no
podemos llamarlo
idDeposito = "";
diametro = 0;
77

altura = 0;
}

} //Cierre del mtodo

public float getDiametro () { return diametro; } //Mtodo de acceso


public float getAltura () { return altura; } //Mtodo de acceso
public String getIdDeposito () { return idDeposito; } //Mtodo de acceso
public float valorCapacidad () { //Mtodo tipo funcin
float capacidad;
float pi = 3.1416f; //Si no incluimos la f el compilador considera que 3.1416 es double
capacidad = pi * (diametro/2) * (diametro/2) * altura;
return capacidad;
}
} //Cierre de la clase
En el mtodo setValoresDeposito nos encontramos un cdigo un tanto extrao: un if donde las
instrucciones a ejecutar se encuentran vacas. Esto es admitido en Java, tanto en un if como en un else o
en otras instrucciones. En este caso, el cdigo equivale a: Si el idDeposito es distinto de una cadena
vaca y el valor_diametro es mayor que cero y el valor_altura es mayor que cero no se hace nada, y en
caso contrario se han de ejecutar las instrucciones indicadas en el else. Este tipo de construcciones no
consideramos conveniente utilizarlas frecuentemente. Tan solo pueden ser indicadas cuando queremos
remarcar que en determinadas circunstancias no se debe ejecutar ninguna instruccin.

Otra cuestin a tener en cuenta es que de momento estamos desarrollando una programacin informal:
el sistema de comentarios no se atiene a lo establecido por el sistema de documentacin de Java, y
hemos incluido algunas sentencias de impresin por consola que normalmente no forman parte del
cdigo de los programas. Usaremos estas y otras tcnicas informales con el fin de facilitar el
aprendizaje, no porque puedan ser recomendadas como tcnicas de programacin.
La segunda clase sera la siguiente:
/* Ejemplo - aprenderaprogramar.com */
/*Esta clase representa un conjunto de depsitos formado por entre 2 y 3 depsitos */
public class GrupoDepositos {
78

//Campos de la clase, algunos de ellos son tipo objetos de otra clase


private Deposito deposito1;
private Deposito deposito2;
private Deposito deposito3;
private String idGrupo;
private int numeroDepositosGrupo;
//Constructor para la clase. En ella se crean objetos de otra clase.
public GrupoDepositos (int numeroDeDepositosGrupo, String valor_idGrupo) {
idGrupo = valor_idGrupo;
switch (numeroDeDepositosGrupo) {
case 1: System.out.println ("Un grupo ha de tener ms de un depsito"); break;
case 2:
deposito1 = new Deposito(); /*Al crear el objeto automticamente se llama al constructor del
mismo, en este caso sin parmetros. ESTO ES EJEMPLO DE SINTAXIS DE CREACIN DE UN
OBJETO, EN ESTE CASO DENTRO DE OTRO */
deposito2 = new Deposito();
numeroDepositosGrupo = 2;
break;

case 3: deposito1 = new Deposito(); deposito2 = new Deposito(); deposito3 = new Deposito();
numeroDepositosGrupo = 3;
break;
default: System.out.println ("No se admiten ms de tres depsitos");
//Esto no evita que se cree el objeto.
break;
79

} //Cierre del switch


} //Cierre del constructor
public int getNumeroDepositosGrupo () { return numeroDepositosGrupo; }
public String getIdGrupo () { return idGrupo; }
public float capacidadDelGrupo () {
otra clase

//Este mtodo usa objetos de otra clase e invoca mtodos de

if (numeroDepositosGrupo == 2) { return (deposito1.valorCapacidad() +


deposito2.valorCapacidad() );
} else { return (deposito1.valorCapacidad() + deposito2.valorCapacidad()+
deposito3.valorCapacidad() ); }
//Si el grupo se ha creado con un nmero de depsitos distinto de 2 o 3 saltar un error en tiempo
de ejecucin
} //Cierre del mtodo
} //Cierre de la clase
Con botn derecho sobre el icono de la clase GrupoDepositos, crea un grupo de depsitos que conste de
3 depsitos y cuyo idGrupo sea Grupo KHP. Invoca los mtodos que devuelven el nmero de
depsitos del grupo, el identificador del grupo y la capacidad de los depsitos del grupo. Como
capacidad debers obtener un valor de aproximadamente 1178.1 unidades cbicas.
Verifica con la calculadora si este valor es correcto y trata de razonar sobre por qu se obtiene este valor
y no otro. Crea tambin distintos objetos de tipo Deposito y utiliza sus mtodos. En el caso de
resultados numricos, comprueba si los resultados que te ofrece el ordenador son correctos
comparndolos con los resultados que te ofrece una calculadora.
Este ejemplo de cdigo, todava muy elemental y rudimentario, tiene un diagrama de clases donde nos
indica que la clase GrupoDepositos usa a la clase Deposito.
A modo de resumen, el siguiente esquema nos indica lo que podemos hacer con este cdigo. De este
ejemplo lo nico que nos interesa es practicar cmo una clase puede usar objetos y mtodos de otra
clase y la sintaxis a emplear. Aunque no hemos creado ningn programa, estamos viendo cmo crear
clases y objetos que intervendrn en los programas.
PALABRAS CLAVE STATIC Y FINAL. CONSTANTES EN JAVA.
En los programas que generemos usualmente intervendrn constantes: valores matemticos como el
nmero Pi, o valores propios de programa que nunca cambian. Si nunca cambian, lo adecuado ser
declararlos como constantes en lugar de cmo variables. Supongamos que queremos usar una constante
como el nmero Pi y que usamos esta declaracin:
80

// Ejemplo aprenderaprogramar.com
public class Calculadora {
private double PI = 3.1416;
public void mostrarConstantePi () { System.out.println (PI); }
constructor, mtodos, cdigo de la clase }
Si creas un objeto de tipo Calculadora, comprobars que puedes invocar el mtodo mostrarConstantePi
para que te muestre el valor por pantalla. No obstante, una declaracin de este tipo presenta varios
problemas. En primer lugar, lo declarado no funciona realmente como constante, sino como variable
con un valor inicial. Prueba a establecer this.PI = 22; dentro del mtodo y vers que es posible, porque
lo declarado es una variable, no una constante. En segundo lugar, cada vez que creamos un objeto de
tipo calculadora estamos usando un espacio de memoria para almacenar el valor 3.1416. As, si
tuviramos diez objetos calculadora, tendramos diez espacios de memoria ocupados con la misma
informacin, lo cual resulta ineficiente. Para resolver estos problemas, podemos declarar constantes en
Java usando esta sintaxis:
CaracterPublico/Privado static final TipoDeLaConstante = valorDeLaConstante;
En esta declaracin intervienen dos palabras clave cuyo significado es importante:
a) static: los atributos miembros de una clase pueden ser atributos de clase o atributos de instancia; se
dice que son atributos de clase si se usa la palabra clave static: en ese caso la variable es nica para
todas las instancias (objetos) de la clase (ocupa un nico lugar en memoria). A veces a las variables de
clase se les llama variables estticas. Si no se usa static, el sistema crea un lugar nuevo para esa variable
con cada instancia (la variable es diferente para cada objeto). En el caso de una constante no tiene
sentido crear un nuevo lugar de memoria por cada objeto de una clase que se cree. Por ello es adecuado
el uso de la palabra clave static. Cuando usamos static final se dice que creamos una constante de
clase, un atributo comn a todos los objetos de esa clase.
b) final: en este contexto indica que una variable es de tipo constante: no admitir cambios despus de
su declaracin y asignacin de valor. final determina que un atributo no puede ser sobreescrito o
redefinido. O sea: no funcionar como una variable tradicional, sino como una constante. Toda
constante declarada con final ha de ser inicializada en el mismo momento de declararla. final tambin se
usa como palabra clave en otro contexto: una clase final (final) es aquella que no puede tener clases que
la hereden. Lo veremos ms adelante cuando hablemos sobre herencia.
Cuando se declaran constantes es muy frecuente que los programadores usen letras maysculas (como
prctica habitual que permite una mayor claridad en el cdigo), aunque no es obligatorio.
Una declaracin en cabecera de una clase como private final double PI = 3.1416; podramos
interpretarla como una constante de objeto. Cada objeto tendr su espacio de memoria con un contenido
invariable. Una declaracin en cabecera de una clase como private static final double Pi = 3.1416; la
interpretamos como una constante de clase. Existe un nico espacio de memoria, compartido por todos
los objetos de la clase, que contiene un valor invariable. Veamos ejemplos de uso:
81

// Ejemplo aprenderaprogramar.com
// Sintaxis: CaracterPublico/Privado static final TipoDeLaConstante = valorDeLaConstante;
private static final float PI = 3.1416f; //Recordar f indica que se trata de un float
private static double PI = 3.1416;
public static final String passwd = "jkl342lagg";
public static final int PRECIO_DEFAULT = 100;
Cuando usamos la palabra clave static la declaracin de la constante ha de realizarse obligatoriamente
en cabecera de la clase, junto a los campos (debajo de la signatura de clase). Es decir, un atributo de
clase hemos de declararlo en cabecera de clase. Si tratamos de incorporarlo en un mtodo obtendremos
un error. Por tanto dentro del mtodo main (que es un mtodo de clase al llevar incorporado static en su
declaracin) no podemos declarar constantes de clase. Por otro lado, final s puede ser usado dentro de
mtodos y tambin dentro de un mtodo main. Por ejemplo una declaracin como final String psswd =
mt34rsm8 es vlida dentro de un mtodo. En resumen: en cabecera de clase usaremos static final para
definir aquellas variables comunes a todos los objetos de una clase.
Modifica el cdigo de la clase Calculadora que vimos anteriormente para declarar PI como una
constante de clase. Luego, intenta modificar el valor de PI usando una invocacin como this.PI =22;.
Comprobars que se produce un error al compilar ya que los valores de las constantes no son
modificables.
EJERCICIO
Define una clase Java denominada Circulo que tenga como atributo de clase (esttico) y constante
numeroPi, siendo esta constante de tipo double y valor 3.1416. Adems la clase tendr el atributo radio
(tipo double) que representa el radio del crculo, y los mtodos para obtener y establecer los atributos.
Tambin debe disponer de un mtodo para calcular el rea del crculo (mtodo tipo funcion areaCirculo
que devuelve el rea) y la longitud del crculo (mtodo tipo funcin que devuelve la longitud). Busca
informacin sobre las frmulas necesarias para crear estos mtodos en internet si no las recuerdas. En
una clase con el mtodo main, declara el cdigo que cree un objeto crculo, le pida al usuario el radio y
le devuelva el rea y la longitud del crculo.
Es posible crear un mtodo en la clase Circulo para establecer el valor de numeroPi? Por qu?
EJEMPLO DE HERENCIA EN JAVA. EXTENDS Y SUPER.
Para declarar la herencia en Java usamos la palabra clave extends. Ejemplo: public class MiClase2
extends Miclase1. Para familiarizarte con la herencia te proponemos que escribas y estudies un pequeo
programa donde se hace uso de ella. Escribe el cdigo de las clases que mostramos a continuacin.
//Cdigo de la clase Persona ejemplo aprenderaprogramar.com
public class Persona {
82

private String nombre;


private String apellidos;
private int edad;
//Constructor
public Persona (String nombre, String apellidos, int edad) {
this.nombre = nombre;
this.apellidos = apellidos;
this.edad = edad;

//Mtodos
public String getNombre () { return nombre; }
public String getApellidos () { return apellidos; }
public int getEdad () { return edad; }
} //Cierre de la clase
//Cdigo de la clase profesor, subclase de la clase Persona ejemplo aprenderaprogramar.com
public class Profesor extends Persona {
//Campos especficos de la subclase.
private String IdProfesor;
//Constructor de la subclase: incluimos como parmetros al menos los del constructor de la superclase

public Profesor (String nombre, String apellidos, int edad) {


super(nombre, apellidos, edad);
IdProfesor = "Unknown"; } //Cierre del constructor
//Mtodos especficos de la subclase
public void setIdProfesor (String IdProfesor) { this.IdProfesor = IdProfesor; }
83

public String getIdProfesor () { return IdProfesor; }


public void mostrarNombreApellidosYCarnet() {
// nombre = "Paco"; Si tratramos de acceder directamente a un campo privado de la superclase,
salta un error

// S podemos acceder a variables de instancia a travs de los mtodos de acceso pblicos de la


superclase
System.out.println ("Profesor de nombre: " + getNombre() + " " + getApellidos() +
" con Id de profesor: " + getIdProfesor() ); }
} //Cierre de la clase

//Cdigo de test aprenderaprogramar.com


public class TestHerencia1 {
public static void main (String [ ] Args) {
Profesor profesor1 = new Profesor ("Juan", "Hernndez Garca", 33);
profesor1.setIdProfesor("Prof 22-387-11");
profesor1.mostrarNombreApellidosYCarnet();}
} //Cierre de la clase
El diagrama de clases y el resultado del test son del tipo que mostramos a continuacin:
herencia, java

Profesor de nombre: Juan Hernndez Garca con Id de profesor: Prof 22-387-11


Los aspectos a destacar del cdigo son:
a) La clase persona es una clase normal definida tal y como lo venimos haciendo habitualmente
mientras que la clase Profesor es una subclase de Persona con ciertas peculiaridades.

84

b) Los objetos de la subclase van a tener campos nombre, apellidos y edad (heredados de Persona) y un
campo especfico IdProfesor. El constructor de una subclase ha de llevar obligatoriamente como
parmetros al menos los mismos parmetros que el constructor de la superclase.
c) El constructor de la subclase invoca al constructor de la superclase. Para ello se incluye,
obligatoriamente, la palabra clave super como primera lnea del constructor de la subclase. La palabra
super ir seguida de parntesis dentro de los cuales pondremos los parmetros que requiera el
constructor de la superclase al que queramos invocar. En este caso solo tenamos un constructor de
superclase que requera tres parmetros. Si p.ej. hubiramos tenido otro constructor que no requiriera
ningn parmetro podramos haber usado uno u otro, es decir, super(nombre, apellidos, edad) super(),
o bien ambos teniendo dos constructores para la superclase y dos constructores para la subclase.
Ejemplo:
En la superclase:

public Persona() {
nombre = "";
apellidos = "";
edad = 0; }
public Persona (String nombre, String apellidos, int edad) {
this.nombre = nombre;
this.apellidos = apellidos;
this.edad = edad;

En la subclase:

public Profesor () {
super();
IdProfesor = "Unknown";}
public Profesor (String nombre, String apellidos, int edad) {
super(nombre, apellidos, edad);
IdProfesor = "Unknown"; }

Modifica el cdigo de las clases Persona y Profesor para que queden con dos constructores tal y como
hemos mostrado aqu. Crea objetos de ambos tipos en BlueJ y prueba sus mtodos.
Qu ocurre si olvidamos poner super como primera lnea de la subclase? Hay dos posibilidades: si la
superclase tiene un constructor sin parmetros, el compilador incluir en segundo plano super de forma
85

automtica y no saltar un error. De cualquier manera se considera contrario al buen estilo de


programacin, ya que no queda claro si se trata de un olvido. Por ello incluiremos siempre la palabra
clave super. La otra posibilidad es que no haya un constructor sin parmetros, en cuyo caso saltar un
error.
A modo de resumen: la inicializacin de un objeto de una subclase comprende dos pasos. La invocacin
al constructor de la superclase (primera lnea del constructor: super) y el resto de instrucciones
propias del constructor de la subclase.
EJERCICIO
Se plantea desarrollar un programa Java que permita la gestin de una empresa agroalimentaria que
trabaja con tres tipos de productos: productos frescos, productos refrigerados y productos congelados.
Todos los productos llevan esta informacin comn: fecha de caducidad y nmero de lote. A su vez,
cada tipo de producto lleva alguna informacin especfica. Los productos frescos deben llevar la fecha
de envasado y el pas de origen. Los productos refrigerados deben llevar el cdigo del organismo de
supervisin alimentaria. Los productos congelados deben llevar la temperatura de congelacin
recomendada. Crear el cdigo de las clases Java implementando una relacin de herencia desde la
superclase Producto hasta las subclases ProductoFresco, ProductoRefrigerado y ProductoCongelado.
Cada clase debe disponer de constructor y permitir establecer (set) y recuperar (get) el valor de sus
atributos y tener un mtodo que permita mostrar la informacin del objeto. Crear una clase
testHerencia2 con el mtodo main donde se cree un objeto de cada tipo y se muestren los datos de cada
uno de los objetos creados.
MODIFICADORES DE ACCESO JAVA: PUBLIC, PRIVATE, PROTECTED.
Hasta ahora habamos dicho que una subclase no tiene acceso a los campos de una superclase de
acuerdo con el principio de ocultacin de la informacin. Sin embargo, esto podra considerarse como
demasiado restrictivo.
Decimos que podra considerarse demasiado restrictivo porque limita el acceso a una subclase como si
se tratara de una clase cualquiera, cuando en realidad la relacin de una superclase con una subclase es
ms estrecha que con una clase externa. Por ello en diferentes lenguajes, Java entre ellos, se usa un nivel
de acceso intermedio que no es ni public ni private, sino algo intermedio que se denomina como
acceso protegido, expresado con la palabra clave protected, que significa que las subclases s pueden
tener acceso al campo o mtodo.
El modificador de acceso protected puede aplicarse a todos los miembros de una clase, es decir, tanto a
campos como a mtodos o constructores. En el caso de mtodos o constructores protegidos, estos sern
visibles/utilizables por las subclases y otras clases del mismo package. El acceso protegido suele
aplicarse a mtodos o constructores, pero preferiblemente no a campos, para evitar debilitar el
encapsulamiento. En ocasiones puntuales s resulta de inters declarar campos con acceso protegido.

La sintaxis para emplear esta palabra clave es anloga a la que usamos con las palabras public y private,
con la salvedad de que protected suele usarse cuando se trabaja con herencia. Desde un objeto de una
subclase podremos acceder o invocar un campo o mtodo declarado como protected, pero no podemos
86

acceder o invocar a campos o mtodos privados de una superclase. Declara un campo de una clase
como protected y en un test crea un objeto de la subclase y trata de acceder a ese campo con una
invocacin directa del tipo interino43.IdProfesor = 54-DY-87.
Java admite una variante ms en cuanto a modificadores de acceso: la omisin del mismo (no declarar
ninguno de los modificadores public, private o protected). En la siguiente tabla puedes comparar los
efectos de usar uno u otro tipo de declaracin en cuanto a visibilidad de los campos o mtodos:
MODIFICADOR
CLASE
PACKAGE
SUBCLASE
TODOS
public
S
S
S
S
protected
S
S
S
No
No especificado
S
S

No
87

No
private
S
No
No
No
EJERCICIO
Considera que ests desarrollando un programa Java donde trabajas con la superclase Profesor y la
subclase ProfesorEmerito. Crea el cdigo para estas clases que cumpla los requisitos que indicamos.
Como atributos de la superclase tendremos nombre (String), edad (int) y aosConsolidados (int)
declarados como protected.
En la subclase se trabajar con el campo adicional aosEmerito declarado como private.
Un mtodo de la subclase ser double obtenerSalarioBase () que obtendr el salario base como (925 +
aosConsolidados * 33.25 + 47.80 * aosEmerito).
Intenta acceder directamente al campo aosConsolidados desde la subclase (como si fuera un campo
ms de la subclase) para implementar este mtodo. Es posible sin utilizar una invocacin a super ni un
mtodo get? Qu ocurre si el atributo en la superclase lo declaras private?
PARA QU SIRVEN LAS INTERFACES EN JAVA
Si una interfaz define un tipo (al igual que una clase define un tipo) pero ese tipo no provee de ningn
mtodo podemos preguntarnos: qu se gana con las interfaces en Java? La implementacin (herencia)
de una interfaz no podemos decir que evite la duplicidad de cdigo o que favorezca la reutilizacin de
cdigo puesto que realmente no proveen cdigo.
En cambio s podemos decir que rene las otras dos ventajas de la herencia: favorecer el mantenimiento
y la extensin de las aplicaciones. Por qu? Porque al definir interfaces permitimos la existencia de
variables polimrficas y la invocacin polimrfica de mtodos. En el diagrama que vimos
anteriormente tanto rboles como arbustos, vehculos y personas son de tipo Actor, de modo que
podemos generar cdigo que haga un tratamiento en comn de todo lo que son actores. Por ejemplo,
podemos necesitar una lista de Actores. Podemos declarar una variable como de tipo Actor (aunque no
puedan existir instancias de Actor) que permita referenciar alternativamente a objetos de las distintas
subclases de la interfaz.
Un aspecto fundamental de las interfaces en Java es hacer lo que ya hemos dicho que hace una interfaz
de forma genrica: separar la especificacin de una clase (qu hace) de la implementacin (cmo lo
hace). Esto se ha comprobado que da lugar a programas ms robustos y con menos errores. Pensemos
88

en el API de Java. Por ejemplo, disponemos de la interfaz List que es implementada por las clases
ArrayList y LinkedList (y tambin por otras varias clases).

El hecho de declarar una variable de tipo lista, por ejemplo List <String> miLista; nos dice que miLista
va a ser una implementacin de List, pero todava no hemos definido cul de las posibles
implementaciones va a ser. De hecho, el cdigo podra definir que se implementara de una u otra
manera en funcin de las circunstancias usando condicionales. O a nivel de programacin,
mantendramos la definicin como List y nos permitira comprobar el rendimiento de distintas
configuraciones (hacer funcionar miLista bien como ArrayList bien como LinkedList viendo su
rendimiento). La variable declarada se crea cuando escribimos miLista = new LinkedList <String> (); o
tambin se puede usar la sintaxis: List <String> miLista = new LinkedList <String> ();
Usar una u otra implementacin puede dar lugar a diferentes rendimientos de un programa. ArrayList
responde muy bien para la bsqueda de elementos situados en posiciones intermedias pero la insercin
o eliminacin de elementos puede ser ms rpida con una LinkedList. Declarando las variables
simplemente como List tendremos la posibilidad de que nuestro programa pase de usar un tipo de lista a
otro tipo.
Como List es un tipo, podemos especificar los mtodos para que requieran List y despus enviarles
como parmetro bien un ArrayList bien un LinkedList sin tener que preocuparnos de hacer cambios en
el cdigo en caso de que usramos uno u otro tipo de lista. En esencia, usando siempre List, el nico
sitio donde habra que especificar la clase concreta sera donde se declara la creacin de la variable, con
lo cual todo nuestro cdigo (excepto el lugar puntual donde se crea la variable) es independiente del
tipo de lista que usemos y esto resulta ventajoso porque pasar de usar un tipo de lista a usar otro
resultar muy sencillo.
Los mtodos de ArrayList en algunos casos definen los mtodos abstractos de List, y en otros casos son
especficos. Recordar que en List todos los mtodos son abstractos por ser una interfaz, aunque no
se indique especficamente en la documentacin del API de Java. Recordar tambin que List, por ser
una interfaz no tiene constructores y no es instanciable. Al ver la documentacin del API nos puede
parecer una clase, pero la ausencia de constructor (aparte del propio nombre en el encabezado) delata
que no se trata de una clase.

Interface List<E>
All Superinterfaces: Collection<E>, Iterable<E>
89

All Known Implementing Classes: AbstractList, AbstractSequentialList, ArrayList, AttributeList,


CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, Vector
Otra ventaja clara de las interfaces es que nos permiten declarar constantes que van a estar disponibles
para todas las clases que queramos (implementando esa interfaz). Nos ahorra cdigo evitando tener que
escribir las mismas declaraciones de constantes en diferentes clases.
EJEMPLO SENCILLO DE INTERFACE EN JAVA
Vamos a ver un ejemplo simple de definicin y uso de interface en Java. Las clases que vamos a usar y
sus relaciones se muestran en el esquema. Escribe el cdigo y ejectalo.

public interface Figura { // Ejemplo aprenderaprogramar.com


float PI = 3.1416f; // Por defecto public static final. La f final indica que el nmero es float
float area(); // Por defecto abstract public
} //Cierre de la interface

public class Cuadrado implements Figura { // La clase implementa la interface Figura

90

private float lado;


public Cuadrado (float lado) { this.lado = lado; }
public float area() { return lado*lado; }
} //Cierre de la clase ejemplo aprenderaprogramar.com

public class Circulo implements Figura{ // La clase implementa la interface Figura


private float diametro;
public Circulo (float diametro) { this.diametro = diametro; }
public float area() { return (PI*diametro*diametro/4f); }
} //Cierre de la clase ejemplo aprenderaprogramar.com

public class Rectangulo implements Figura{ // La clase implementa la interface Figura


private float lado; private float altura;
public Rectangulo (float lado, float altura) { this.lado = lado; this.altura = altura; }
public float area() { return lado*altura; }
} //Cierre de la clase ejemplo aprenderaprogramar.com

import java.util.List; import java.util.ArrayList; //Test ejemplo aprenderaprogramar.com

91

public class TestInterface {


public static void main (String [ ] Args) {
Figura cuad1 = new Cuadrado (3.5f); Figura cuad2 = new Cuadrado (2.2f); Figura cuad3 = new
Cuadrado (8.9f);
Figura circ1 = new Circulo (3.5f); Figura circ2 = new Circulo (4f);
Figura rect1 = new Rectangulo (2.25f, 2.55f); Figura rect2 = new Rectangulo (12f, 3f);
List <Figura> serieDeFiguras = new ArrayList <Figura> ();
serieDeFiguras.add (cuad1); serieDeFiguras.add (cuad2); serieDeFiguras.add (cuad3);
serieDeFiguras.add (circ1); serieDeFiguras.add (circ2); serieDeFiguras.add (rect1);
serieDeFiguras.add (rect2);
float areaTotal = 0;
for (Figura tmp: serieDeFiguras) {

areaTotal = areaTotal + tmp.area();

System.out.println ("Tenemos un total de " + serieDeFiguras.size() + " figuras y su rea total es de " +
areaTotal + " uds cuadradas") } } //Cierre del main y de la clase
El resultado de ejecucin podra ser algo as:

Tenemos un total de 7 figuras y su rea total es de 160.22504 uds cuadradas

En este ejemplo comprobamos que la interface Figura define un tipo. Podemos crear un ArrayList
de figuras donde tenemos figuras de distintos tipos (cuadrados, crculos, rectngulos) aprovechndonos
del polimorfismo. Esto nos permite darle un tratamiento comn a todas las figuras. En concreto, usamos
un bucle for-each para recorrer la lista de figuras y obtener un rea total.
IMPLEMENTAR UNA INTERFACE DEL API JAVA. EJEMPLO.
El API de Java define interfaces que aparte de usarlas para definir tipos, nosotros podemos implementar
en una clase propia en nuestro cdigo. Esto tiene cierta similitud con hacer una redefinicin de un
mtodo (ya hemos visto cmo redefinir mtodos como toString()), pero no es exactamente lo mismo.
Para empezar, algunos mtodos como toString() estn definidos en la clase Object. Estos mtodos
declarados en la clase Object los podemos redefinir en una clase propia sin necesidad de escribir nada
92

en cabecera de la clase, puesto que por defecto todo objeto hereda de Object. Para utilizar interfaces,
como la interfaz Comparable, habremos de escribir en cabecera de la clase:

public class NombreDeLaClase implements Comparable <NombreDeLaClase> { }

Por ejemplo public class Persona implements Comparable <Persona>.


Qu inters tiene implementar una interface del API si no nos proporciona cdigo ninguno? Tal
y como dijimos en su momento, una interface puede verse en relacin a la programacin como una
norma urbanstica en una ciudad. Si lees la documentacin de la interfaz, aunque no proporciona
cdigo, s proporciona instrucciones respecto a caractersticas comunes para las clases que la
implementen y define qu mtodos han de incluirse para cumplir con la interfaz y para qu servirn
esos mtodos. Si implementamos la interface, lo que hacemos es ajustarnos a la norma. Y si todos los
programadores se ajustan a la misma norma, cuando un programador tiene que continuar un programa
iniciado por otro no tiene que preguntarse: qu mtodo podr usar para comparar varios objetos de este
tipo y ponerlos en orden? Y no hay que preguntrselo porque en general los programadores se cien a lo
establecido por el API de Java: para comparar varios objetos y ponerlos en orden (orden natural) se
implementa la interfaz Comparable y su mtodo compareTo(). Y adems, ya sabemos qu tipo ha de
devolver ese mtodo y cmo ha de funcionar, porque as lo indica la documentacin de la interface.
Muchas clases del API de Java ya tienen implementada la interface Comparable. Por ejemplo la clase
Integer tiene implementada esta interfaz, lo que significa que el mtodo compareTo() es un mtodo
disponible para cualquier objeto de tipo Integer.
No podemos conocer ni todas las clases ni todas las interfaces del API de Java. No obstante, a medida
que vayamos realizando programas y adquiriendo prctica con Java, nos daremos cuenta de que algunas
clases e interfaces son muy usadas. A base de usarlas, iremos memorizando poco a poco sus nombres y
mtodos. Otras clases o interfaces las usaremos ocasionalmente y recurriremos a la consulta de
documentacin del API cada vez que vayamos a usarlas. Y otras clases o interfaces quiz no lleguemos
a usarlas nunca.
EJERCICIO
Se plantea desarrollar un programa Java que permita representar la siguiente situacin. Una
instalacin deportiva es un recinto delimitado donde se practican deportes, en Java interesa disponer de
un mtodo int getTipoDeInstalacion(). Un edificio es una construccin cubierta y en Java interesa
disponer de un mtodo double getSuperficieEdificio(). Un polideportivo es al mismo tiempo una
instalacin deportiva y un edificio; en Java interesa conocer la superficie que tiene y el nombre que
tiene. Un edificio de oficinas es un edificio; en Java interesa conocer el nmero de oficinas que tiene.
Definir dos interfaces y una clase que implemente ambas interfaces para representar la situacin
anterior. En una clase test con el mtodo main, crear un ArrayList que contenga tres polideportivos y
dos edificios de oficinas y utilizando un iterator, recorrer la coleccin y mostrar los atributos de cada
elemento. Entre qu clases existe una relacin que se asemeja a la herencia mltiple?
93

/** * Este metodo lee una imagen bmp, gif, jpg, png y la * guarda en el atributo dbi del
tipo BufferedImage * @param frame Ventana sobre la que se despliega el cuadro * de
dialogo JFileChooser */
public void leeImagen(JFrame frame) { JFileChooser fc = new JFileChooser();
// Elimina el filtro *.*
fc.setAcceptAllFileFilterUsed(false);
//Crea el filtro para las extensiones validas
FileNameExtensionFilter extFiltro = new FileNameExtensionFilter( "Images", "bmp", "gif",
"jpg", "png");
// Establece el filtro para las extensiones validas
fc.setFileFilter(extFiltro);
//Despliega el cuadro de dialogo para seleccionar la imagen a abrir
int returnVal = fc.showOpenDialog(frame);
// Si se selecciono una imagen
if (returnVal == JFileChooser.APPROVE_OPTION) {
// Obtiene el objeto File de la imagen seleccionada
file = fc.getSelectedFile(); try {
// lee la imagen y la guarda en el atributo obi del tipo BufferedImage
BufferedImage obi = ImageIO.read(file);
94

// Hace que la referencia dbi apunte a obi


dbi = obi; } catch (IOException e) { JOptionPane.showMessageDialog(frame, "Error al
cargar imagen"); return; } } }
___________________________________________
PROGRAMA MONTADO Y PROBADO = PROYECTO. JAVA: metodosio2
*/ public class metodosio2 {
/** * @param args the command line arguments */
public static void main(String[] args) {
String userDir = System.getProperty("user.dir");
String separador = System.getProperty("file.separator");
System.out.println("Directorio del usuario: " + userDir);
System.out.println("Separador: " + separador);
File file1 = new File(userDir);
System.out.println("Ruta abstracta del directorio del usuario: " + file1);
File file2 = new File("src metodosio2.java");
System.out.println("Caracteristicas del archivo: src metodosio2.java: ");
System.out.println("Nombre: " + file2.getName());
System.out.println(file2.getName() + (file2.exists()? " ": " no ") + "existe");
System.out.println("Tamao " + file2.length() + " bytes");
System.out.println("Ruta: " + file2.getPath());
System.out.println("Ruta abstracta: " + file2);
System.out.println("Ruta absoluta: " + file2.getAbsolutePath());
System.out.println("Ruta abstracta absoluta: " + file2.getAbsoluteFile());
System.out.println(file2.getName() + (file2.isFile()? " ": " no ") + "es un archivo");
System.out.println(file2.getName() + (file2.isDirectory()? " ": " no ") + "es un directorio");
___________________________________________________
System.out.println("n");
System.out.println("Caracteristicas
del
padre
de:
srcpruebasPruebaFile.java:
");
System.out.println("Ruta:
"
+
file2.getParent());
System.out.println("Ruta abstracta: " + file2.getParentFile()); System.out.println("Ruta
absoluta: " + file2.getParentFile().getAbsolutePath()); System.out.println("Ruta abstracta
absoluta: " + file2.getParentFile().getAbsoluteFile()); System.out.println(file2.getParent() +
(file2.getParentFile().isFile()?
"
":
"
no
")
+
"es
un
archivo");
System.out.println(file2.getParent() + (file2.getParentFile().isDirectory()? " ": " no ") + "es
un directorio"); File dir[] = file1.listFiles(); System.out.println("Archivos del directorio del
usuario: "); for(File file: dir) { System.out.println(file); }
http://www.javaya.com.ar/detalleconcepto.php?codigo=88&inicio

Mtodos con parmetros.


Un mtodo puede tener parmetros:
public void [nombre del mtodo]([parmetros]) {
[algoritmo]
}

95

Los parmetros los podemos imaginar como variables locales al mtodo, pero su valor se inicializa con
datos que llegan cuando lo llamamos. Estos parmetros son propios (exclusivos) del mtodo, pueden
tener el mismo nombre de un atributo de clase, pero tienen diferente mbito y duracin. En este caso,
para hacer que los parmetros del mtodo sean las variables de la clase, hay que redactar la siguiente
sentencia:
This. parmetro = variable con el mismo nombre (ej: this.x = x)

Problema 1:
Confeccionar una clase que permita ingresar valores enteros por teclado y nos muestre la tabla de
multiplicar de dicho valor. Finalizar el programa al ingresar el -1.
Programa:
import java.util.Scanner;
public class TablaMultiplicar {
//mtodo cargarValor sin parmetros:
public void cargarValor() {
//Cdigo: operaciones a ejecutar
//Crea un nuevo objeto de nombre teclado pertenece a la clase Scanner
Scanner teclado=new Scanner(System.in);
//declara una variable propia de nombre valor
int valor;
//Mtodo do:
do {
//pide ingresar un valor por teclado:
System.out.print("Ingrese valor:");
valor=teclado.nextInt();
if (valor!=-1) {
//invoca al mtodo calcular (que est ms adelante)
Y le asigna el valor recibido a su parmetro (int v)
calcular(valor);
}
} while (valor!=-1);
}
//mtodo con parmetros (int v) para calcular los valores de
la tabla de multiplicar del valor recibido en su invocacin
public void calcular(int v) {
for(int f=v;f<=v*10;f=f+v) {
System.out.print(f+"-");
}
}
//mtodo principal, en el cual se crea un Nuevo
Objeto llamado tabla
public static void main(String[] ar) {
TablaMultiplicar tabla = new TablaMultiplicar();
//este objeto tabla llama al mtodo cargarValor,
ya que de no declararse esta sentencia, el programa
entero no hara nada, pues el mtodo inicial no arrancara.
tabla.cargarValor();
}

96

En esta clase no hemos definido ningn atributo, ya que el objeto de la clase Scanner lo requerimos en
un solo mtodo, por ello lo definimos como una variable local.
El mtodo calcular recibe un parmetro de tipo entero, luego lo utilizamos dentro del mtodo para
mostrar la tabla de multiplicar de dicho valor, para esto inicializamos la variable f con el valor que llega
en el parmetro. Luego de cada ejecucin del for incrementamos el contador f con el valor de v.
public void calcular(int v) {
for(int f=v;f<=v*10;f=f+v) {
System.out.print(f+"-");
}
}

Un mtodo puede no tener parmetros como hemos visto en problemas anteriores o puede tener uno o
ms parmetros (en caso de tener ms de un parmetro los mismos se separan por coma)
El mtodo cargarValores no tiene parmetros y tiene por objetivo cargar un valor entero por teclado y
llamar al mtodo calcular para que muestre la tabla de multiplicar del valor que le pasamos por teclado:
public void cargarValor() {
Scanner teclado=new Scanner(System.in);
int valor;
do {
System.out.print("Ingrese valor:");
valor=teclado.nextInt();
if (valor!=-1) {
calcular(valor);
}
} while (valor!=-1);
}

Como vemos al mtodo calcular lo llamamos por su nombre y entre parntesis le pasamos el dato a
enviar (debe ser un valor o variable entera)
En este problema en la main solo llamamos al mtodo cargarValor, ya que el mtodo calcular luego es
llamado por el mtodo cargarValor:
public static void main(String[] ar) {
TablaMultiplicar tabla;
tabla=new TablaMultiplicar();
tabla.cargarValor();
}

Mtodos que retornan un dato.


Un mtodo puede retornar un dato:
public [tipo de dato] [nombre del mtodo]([parmetros]) {
[algoritmo]
return [tipo de dato]
}

97

Cuando un mtodo retorna un dato en vez de indicar la palabra clave void previo al nombre del mtodo
indicamos el tipo de dato que retorna. Luego dentro del algoritmo en el momento que queremos que
finalice el mismo y retorne el dato empleamos la palabra clave return con el valor respectivo.

Problema 2:
Confeccionar una clase que permita ingresar tres valores por teclado. Luego mostrar el mayor y el
menor.
Programa:
import java.util.Scanner;
public class MayorMenor {
public void cargarValores() {
Scanner teclado=new Scanner(System.in);
System.out.print("Ingrese primer valor:");
int valor1=teclado.nextInt();
System.out.print("Ingrese segundo valor:");
int valor2=teclado.nextInt();
System.out.print("Ingrese tercer valor:");
int valor3=teclado.nextInt();
int mayor,menor;
mayor=calcularMayor(valor1,valor2,valor3);
menor=calcularMenor(valor1,valor2,valor3);
System.out.println("El valor mayor de los tres es:"+mayor);
System.out.println("El valor menor de los tres es:"+menor);
}
public int calcularMayor(int v1,int v2,int v3) {
int m;
if(v1>>v2 && v1>v3) {
m=v1;
} else {
if(v2>v3) {
m=v2;
} else {
m=v3;
}
}
return m;
}
public int calcularMenor(int v1,int v2,int v3) {
int m;
if(v1<v2 && v1<v3) {
m=v1;
} else {
if(v2<v3) {
m=v2;
} else {
m=v3;
}
}
return m;
}

98

public static void main(String[] ar) {


MayorMenor maymen=new MayorMenor();
maymen.cargarValores();
}
}

Si vemos la sintaxis que calcula el mayor de tres valores enteros es similar al algoritmo visto en
conceptos anteriores:
public int calcularMayor(int v1,int v2,int v3) {
int m;
if(v1>v2 && v1>v3) {
m=v1;
} else {
if(v2>v3) {
m=v2;
} else {
m=v3;
}
}
return m;
}

Lo primero que podemos observar que el mtodo retorna un entero y recibe tres parmetros:
public int calcularMayor(int v1,int v2,int v3) {

Dentro del mtodo verificamos cual de los tres parmetros almacena un valor mayor, a este valor lo
almacenamos en una variable local llamada "m", al valor almacenado en esta variable lo retornamos al
final con un return.
La llamada al mtodo calcularMayor lo hacemos desde dentro del mtodo cargarCalores:
mayor=calcularMayor(valor1,valor2,valor3);

Debemos asignar a una variable el valor devuelto por el mtodo calcularMayor. Luego el contenido de
la variable mayor lo mostramos:
System.out.println("El valor mayor de los tres es:"+mayor);

La lgica es similar para el clculo del menor.


METODOS
http://elvex.ugr.es/decsai/java/pdf/4B-methods.pdf
____________________
Podemos hacer un resumen de los atributos que pueden tener campos, mtodos o clases:
Campo: {private | public | protected} {final} {static}
Mtodo: {private | public | protected} {final | abstract} {static}
Clase: {public} {final | abstract}
99

Slo se puede especificar uno de los atributos puestos en la misma llave.


Las palabras private, protected y public son atributos de un campo o un mtodo y su
significado es el siguiente:
private: El campo o mtodo slo es visible dentro de la clase donde se define.
protected: El campo o mtodo es visible en la clase en donde se define y desde otras
clases del mismo paquete y en cualquiera de sus subclases (estn o no en el mismo
paquete).
public: El campo o mtodo es visible en cualquier clase.
Ninguna de las anteriores: El campo o mtodo es visible en cualquiera de las clases
pertenecientes al paquete en donde se define.
Al declarar una clase se puede especificar que es pblica usando el atributo public. De
este modo la clase podr ser usada por cualquier otra clase. Si la clase no es pblica
entonces la clase slo puede ser usada dentro del paquete que la contiene.
STATIC:
Sirve para crear miembros que pertenecen a la clase, y no a una instancia de la clase.
Esto implica, entre otras cosas, que no es necesario crear un objeto de la clase para poder
acceder a estos atributos y mtodos.
En ocasiones es necesario o conveniente generar elementos que tomen un mismo valor
para cualquier nmero de instancias generadas o bien invocar/llamar mtodos sin la
necesidad de generar instancias, y es bajo estas dos circunstancias que es empleado el
calificador static.
Dos aspectos caractersticos de utilizar el calificador static en un elemento Java son los
siguientes:
- No puede ser generada ninguna instancia (uso de new) de un elemento static puesto
que solo existe una instancia.
- Todos los elementos definidos dentro de una estructura static deben ser static ellos
mismos, o bien, poseer una instancia ya definida para poder ser invocados.
NOTA: Lo anterior no implica que no puedan ser generadas instancias dentro de un
elemento static; no es lo mismo llamar/invocar que crear/generar.
FINAL:
Indica que una variable, mtodo o clase no se va a modificar, lo cul puede ser til para
aadir ms semntica, por cuestiones de rendimiento, y para detectar errores.
- Si una variable se marca como final, no se podr asignar un nuevo valor a la variable.
- Si una clase se marca como final, no se podr extender la clase.
- Si es un mtodo el que se declara como final, no se podr sobreescribir.

100

Algo muy a tener en cuenta a la hora de utilizar este modificador es que si es un objeto lo
que hemos marcado como final, esto no nos impedir modificar el objeto en s, sino tan
slo usar el operador de asignacin para cambiar la referencia. Por lo tanto:
+ expand source
NOTA: Una variable con modificadores static y final sera lo ms cercano en Java a las
constantes de otros lenguajes de programacin.
ABSTRACT:
La palabra clave abstract indica que no se provee una implementacin para un cierto
mtodo, sino que la implementacin vendr dada por las clases que extiendan la clase
actual. Una clase que tenga uno o ms mtodos abstract debe declararse como abstract a
su vez.
_______________________
bueno tengo varias clases y en una en especifo ya estan setiadas las variables y nesesito
su contenido en otra clase como las llamo ? ya las declare publicas pero no se como
llamarlas desde la otra clase

declarelas privada y haga un metodo que devuelva dicha variables, solo tendrias
que hacer lo siguiente
clase x = new clase;
int y = x.obtenervariable();
el metodo en la clase "clase" seria
private int variable_y = 0;
Public int obtenervariable()
{
return variable_y;
}

No se puede hacer lo que quieres, las variables pueden ser globales o locales, si
son globales iran justo debajo de la declaracion de la clase pero tampoco se las
podra llamar si no es a traves de un objeto, si son locales quiere decir que solo
funcionan dentro del metodo donde fueron creadas.
Si quisieras llamar una variable desde otro clase primero deberias crear un objeto
de esa otra clase asi:
NombreClase NombreObjeto=new NombreClase();
donde NombreObjeto sera el nombre que vas a usar para acceder a esa clase y
NombreClase sera el nombre de la clase que quieres usar. Asi mismo las clases que
quieras usar deben estar en el mismo paquete por lo que antes incluso de declarar
la clase en un archivo deberas declarar el paquete donde se agrupan esas clases
package NombrePaquete;

Si no estan las dos clases en el mismo paquete es imposible poder cojer


informacion de otra clase.
101

Y por ultimo una vez tengas las 2 clases en el mismo paquete y creado el objeto
simplemente deberas escribir lo siguiente:
NombreObjeto.NombreVariable;
Con eso accederias a la variable del objeto aunque no es la forma estandar, la
forma estandar seria usando getters para acceder a las variables(atributos) del
objeto y los setters para modificar los valores de los atributos.

Otra opcin sera declarar las variables como atributos estticos de la clase. as, solo hay
una en tiempo de ejecucin y todas las llamadas a la variable son al mismo lugar, algo asi
como:
public class Variable {
public static int variableEntera = 0;
}
As ya la puedes acceder como Variable.variableEntera.
otra opcin, que a fin de cuentas es la misma gata pero revolcada, es crear atributos
estticos privados en la clase e implementar accesores.
public class Variable {
private static String variableString = "";
public String getVariableString(){
return variableString;
}
public void setVariableString(String valor){
variableString = valor;
}
}
Ahora, la pregunta de los 64 millones, porque las variables son estticas? Con lo esttico
creas "atributos" o "variables" de clase, los cuales no requieres instanciar un objeto de la
clase para poderlas usar. Si no fueran estticas, cada vez que hagas un new Variable(); te
creara un objeto nuevo con los atributos vacos y morira cada vez que el cdigo o
funcin o bloque sobre el que est corriendo termine.
______________
Modificadores de clases y mtodos: STATIC, FINAL, ABSTRACT.
STATIC:
Sirve para crear miembros que pertenecen a la clase, y no a una instancia de la clase.
Esto implica, entre otras cosas, que no es necesario crear un objeto de la clase para poder
acceder a estos atributos y mtodos.
102

En ocasiones es necesario o conveniente generar elementos que tomen un mismo valor


para cualquier nmero de instancias generadas o bien invocar/llamar mtodos sin la
necesidad de generar instancias, y es bajo estas dos circunstancias que es empleado el
calificador static.
Dos aspectos caractersticos de utilizar el calificador static en un elemento Java son los
siguientes:
- No puede ser generada ninguna instancia (uso de new) de un elemento static puesto
que solo existe una instancia.
- Todos los elementos definidos dentro de una estructura static deben ser static ellos
mismos, o bien, poseer una instancia ya definida para poder ser invocados.
NOTA: Lo anterior no implica que no puedan ser generadas instancias dentro de un
elemento static; no es lo mismo llamar/invocar que crear/generar.
FINAL:
Indica que una variable, mtodo o clase no se va a modificar, lo cul puede ser til para
aadir ms semntica, por cuestiones de rendimiento, y para detectar errores.
- Si una variable se marca como final, no se podr asignar un nuevo valor a la variable.
- Si una clase se marca como final, no se podr extender la clase.
- Si es un mtodo el que se declara como final, no se podr sobreescribir.
Algo muy a tener en cuenta a la hora de utilizar este modificador es que si es un objeto lo
que hemos marcado como final, esto no nos impedir modificar el objeto en s, sino tan
slo usar el operador de asignacin para cambiar la referencia. Por lo tanto:
+ expand source
NOTA: Una variable con modificadores static y final sera lo ms cercano en Java a las
constantes de otros lenguajes de programacin.
ABSTRACT:
La palabra clave abstract indica que no se provee una implementacin para un cierto
mtodo, sino que la implementacin vendr dada por las clases que extiendan la clase
actual. Una clase que tenga uno o ms mtodos abstract debe declararse como abstract a
su vez.
http://www.disi.unal.edu.co/~gjhernandezp/Java/MaterialDeClase/Teoria/pdf/03Modifiers_cont.pdf
_________________
Tu nuevo cdigo hotmail es GWPPM-ZCD4Y-WXCLL-X8KJF-TNYF4
23.- Crear proyecto, package y ficheros para una aplicacin NetBeans
Al crear un proyecto NetBeans, por defecto, crea un package y dentro un fichero .java en
modo texto.

103

Pero podemos aadir mas packages y dentro de los packages podemos aadir mas
ficheros en modo texto o grafico o borrar los que no interesen.
En toda la aplicacin solo ser necesario que haya una clase con el mtodo main que es
impresicindible para poder ejecutarla. En realidad puede haber mas mtodos main en
otros ficheros de la aplicacin. Asi podremos probarlo y ejecutarlo de manera
independiente sin lanzar toda la aplicacion, pero para ejcutar la aplicacion solo se podra
hacer desde el fichero con metodo main que hemos definido.
a) Crear proyecto
Esta es la ventana que se muestra de NetBeans una vez instalado.
Marco con una flecha donde aparecer la aplicacin que voy a crear.
1.1.- Crear una aplicacin
Para ello despliego el menu File y elijo "New Proyect"
Esta es la ventana que se muestra, como la opcin es realizar una aplicacin selecciono
las opciones que he marcado en la captura:
Tras pulsar Next se muestra esta ventana:
En ella he puesto el nombre que quiero a la aplicacin, he seleccionado el directorio
donde quiero guardarlo (tambin se puede dejar por defecto) y he marcado para que cree
automticamente una clase con el mtodo main.
Pulso Finish y esto es lo que se muestra:
Vemos:
La nueva aplicacin en la ventana Projetscon su package (multiplicacion2012) y su
fichero Multiplicacion2013
En la ventana de trabajo (Source) vemos el cdigo creado por defecto en modo texto:
una clase y dentro de ella su mtodo main que indica que esta clase es ejecutable. Esta
clase funciona en modo texto, asi que si queremos trabajar en modo grfico tenemos que
instanciar en ella una llamada a una clase en modo grfico, tambien podemos borrarla y
crear una clase con un frame (modo grfico) que incorpora tambin un metodo main.
Vemos tambin la ventana de salida de datos (Output). Ahora tendremos que aadir
cdigo para que realice la tarea que nos interese.
En la ventana de trabajo aparecen palabras como:
package (paquete): Permite identificar clases que pertenecen a la misma aplicacin. En
esta ocasin se ha creado al crear el la aplicacin, pero tambin pueden aadirse nuevos
packages.
public class: En este caso es una clase, esta seria la clase principal. Pueden haber otras
clases (en flecha verde donde empieza y donde termina)
public static void main: Est dentro de la clase principal, es el mtodo main necesario
para ejercutar las aplicacin (en flecha azul donde empieza y donde termina)
Si ejecutamos (botn derecho sobre el listado) nos dar el mensaje que vemos en la
ventana de salida/Output: "BUILD SUCCESSFUL (total time: 0 seconds)".
b) Crear un fichero en NetBeans
104

El primer fichero se ha creado al generar la aplicacin porque asi hemos indicado,


contiene la clase principal y dentro de ella el mtodo main si hemos marcado la opcin al
crear la aplicacin.
Si necesitamos ms ficheros primero tenemos que crearlo y luego rellenarlo a mano con
el cdigo que necesitemos (o con copiar y pegar):
Para crearlo: botn derecho sobre package multiplicacion2012MET2-->New--> Se
despliega la ventana de la siguiente captura:
Con Java Main Class podemos crear una clase con el mtodo main. En realidad puede
haber varios ficheros con su clase y metodo main. La ventaja es que pueden ejecutarse
de manera independiente, aunque tambien de manera integrada con las correspondientes
llamadas desde el fichero que har de lanzador de la aplicacin (en este caso los metodos
main en otros ficheros no interfieren). Esto es interesante mientras estamos
programando.
Con Java Class crearemos un fichero con una clase y sin mtodo main, ideal para incluir
en l los mtodos, las variables y operaciones con ellas que luego podremos instanciar
(ver 04.3.- Variables, clases, mtodos)
y clases secundarias si es necesario). Tambin podemos crar otro package, jFrame,
jPanel...
Si pulsamos Other... salen ms opciones, aunque no tienen un frecuente uso.

Nota:
Para crear un fichero en modo grfico seleccionaremos la opcin "JFrame Form"
105

Si hay ficheros en modo texto que no interesen pueden borrarse: fichero-->boton


derecho-->eliminar
Se despliega esta ventana, escribimos el nombre y pulsamos Finish:
Se crea el fichero y dentro de l una clase. Ya solo queda copiar a mano o cortar y pegar
el cdigo que queramos ejecutar.
Es importante que el nombre de la clase que copiamos y pegamos coincida con el del
fichero, si no, podemos cambiarlo a mano
En este caso hemos creado una clase sin mtodo Main, con lo que no podremos ejecutarla
directamente. Pero si de manera indirecta a traves de una instancia (ver 04.3.- Variables,
clases, mtodos) en la clase principal (main).
c) Crear un package
Por defecto ya se crea uno que contiene el/los ficheros de la aplicacin. Pero podemos
crear mas.
Botn derecho sobre el proyecto, en este caso MetodosMultiplicacion2012, o tambien
sobre "Source Package". Seguimos la secuencia de la captura o, si no se muestra lo que
queremos crear pulsamos en Other... y lo seleccionamos desde las opcions que nos
muestra.
En este caso pulsamos Java Package:
En este ejemplo hemos creado una aplicacin que funciona en modo texto. El
procedimiento es muy parecido para crear aplicaciones en modo grafico ver apartado b)
Crear un fichero en NetBeans (nota)

106

http://es.slideshare.net/JhomaraLuzuriaga/programacion-en-java-2
Programacion en JAVA 2
1. 1. PROGRAMACIN GRFICA CON COMPONENTES SWING
Swing es una biblioteca grfica para Java. Incluye widgets para interfaz grfica de usuario.
Una interfaz es lo que le permite a un usuario comunicarse con unprograma a travs de
componentes visuales como cajas de texto, botones,desplegables, tablas, etc.
1.1. COMPONENTE Un componente no es ms que un objeto que representa un elemento
de unainterfaz grfica y que en su mayora tienen una representacin grfica. Se
puededividir en dos tipos:1. Simples o atmicos: Son los que no estn formados por otros
componentes: Ejemplo: Etiquetas, botones, cajas de texto.2. Contenedores: Son
componentes que pueden contener a otros. Contenedores de Alto Nivel: Son aquellos
que brindan un espacio dentro de la pantalla para todos los elementos de una interfaz
grfica. Ejemplo: Frames, Applet. Contenedores intermedios: Permiten agrupar y
organizar los componentes de una interfaz grfica dentro de un contenedor de alto nivel.
Ejemplo: PanelesEl patrn de desarrollo que utiliza SWING es MVC (Modelo Vista
Controlador), quepermite dividir una aplicacin en 3 partes: o Modelo: Datos o Vista:
Interfaz grfica o Controlador: Permite manejar las interacciones del usuario con la
interfaz grfica y a su vez manejar los cambios entre la vista y el modelo.
1.2. JERARQUA DE COMPONENTESTodos los componentes para el diseo de una interfaz
grfica obedecen a unajerarqua de clases.La clase principal es java.awt.Component de la
cual se heredan componentescomo java.awt.Button, java.awt.Label, etc..., y tambin se
hereda la clasejava.awt.Container que representa a un objeto contenedor. Los
componentessimples derivan de la clase JComponent, mientras los contenedores de la
claseWindow.
2. Container Window JComponent PanelFrame Dialog AbstractButton JTextComponent
.. AppletJFrame JDialog JButton .. JTextField JTextArea ..
1.3. CONTENEDORES
1.3.1. Clase JFrameJAVA Frame es el componente, control u objeto principal de una
aplicacion visual o grfica en java. Para crear un Frame deberemos crear una instancia de
107

JFrame, y si deseamos modificar algunas propiedades de la ventana debemos crear una


clase queextienda de JFrame.
Ejemplo:
import javax.swing.*;
class Frame extends JFrame {
//el constuctor
public Frame(){
//Este es uno de los mtodos que nuestra clase Frame ha //heredado de JFrame. Pone un
ttulo a la ventana setTitle("Hola!!!");
//mtodo heredado que le da un tamao a la ventana
setSize(300,200); setVisible(true);
}}
Las ventanas JFrame son invisibles por defecto, se debe modificar la propiedad pordefecto
de JFrame de manera que nuestra ventana sea visible, para esto sesobreescribe el
mtodo con el parmetro true.
setVisible(true)
Algunos mtodos de JFrame son: setResizable(boolean): Permite hacer modificable el
tamao de la ventana
setState(int): Modificar el tamao de la ventana, recibe como parmetro un valor entero
que corresponde a una constante de JFrame, que puede ser:
JFrame.NORMAL, JFrame.ICONFIED.setExtendedState(int): Permite ampliar los estados de
una ventana.
setLocationRelativeTo(Component): Ubicar un componente en base a un segundo
componente enviado como parmetro. Para ubicar la ventana en el centro de la pantalla
el parmetro deber ser null. EJERCICIO: Crear un proyecto DiseoVentanas y en una clase
ejecutable crear 5 ventanas,cada una visualizada en un estado diferente (minimizado,
maximizado,max_horizontal, max_vertical, y normal centrado), estableciendo un ttulo en
cadauna con el estado de la ventana.
1.3.2. Clase JDialog: JDialog es un Componente que sirve para presentar dilogos que son
ventanas auxiliares que se presentan cuando se registra un evento dentro de un
programa,sirven para prevencin o en su defecto se puede utilizar para dar informacin
sobre algo, los dilogos que JDialog muestra pueden ser modales o no modales,
estoquiere decir que si son modales la ventana del dilogo bloquea las entradas a otras
ventanas, este tipo de dilogos se pueden hacer tambin con JOptionPane.Todos los
dilogos dependen de un frame, las modificaciones que se le hagan alframe afectaran a el
dilogo, en caso de que el frame sea cerrado, minizado omaximizado, sus dilogos
tendrn el mismo comportamientoUn JDialog siempre deber tener un componente Parent
del cual se derive, que debe ser un contenedor de alto nivel y su efecto modal o no, de
manera quecuando se crea una instancia de esta clase se deber establecer estos
parmetros.
Ejemplo:Frame ventana= new Frame();
JDialog cuadroDialogo= new JDialog(ventana, true);
En este caso hemos creado un JDialog cuyo parent es un JFrame ventana. LosJDialog
obedecen un evento, es decir se mostrarn cuando sobre el parent serealice algn evento
que invoque la aparicin del JDialog.
1.3.3. Clase JPanel: JPanel es un objeto de los llamados "contenedores". Es as porque
sirven para contener otros objetos.Una de las ventajas de aadir paneles sobre nuestro
108

frame es que los paneles al derivar de JComponent poseen el mtodo paintComponent


que permite dibujar y escribir texto sobre el panel de modo sencillo.Para aadir un JPanel
a nuestro frame primero obtenemos uno de los objetos que forman el frame: el panel
contenedor (content pane). Para ello invocaremos al mtodo getContentPane de nuestro
JFrame.
El objeto que nos devuelve ser detipo
Container:Container [nombre_del_contentpane] = frame.getContentPane();
A continuacin invocamos al mtodo add del Container obtenido para aadir el panel,
pasndole el propio panel al mtodo:
[nombre_del_contentpane].add(nombre_del_panel);
Ejemplo:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class Frame extends JFrame {
public Frame(){ setTitle("Hola!!!");
setSize(300,200);
//Le pido al Frame su objeto contenedor
Container contentpane = getContentPane();
//Creo un objeto de tipo
JPanel JPanel panel = new JPanel();
//Aado el panel en el objeto contenedor del frame
contentpane.add(panel);
//Pongo el color de fondo del panel de color rojo
panel.setBackground(Color.RED);
}}
Para agregar componentes a un panel se utiliza el mtodo add: panel.add(new
JButton(Click aqu));Si no sealamos la ubicacin de los componentes en el panel, stos
se ubicanconforme se vayan aadiendo de manera horizontal, uno despus de otro en
todoel ancho de la ventana.Para visualizar el Frame que hemos creado se aade a la clase
el mtodo maindentro del cual se crear un objeto de nuestra clase Frame. La clase
JFrameimplementa la interfaz Runneable, la cual permite ejecutar y visualizar el
Framehasta que el usuario lo cancele.
public static void main(String[] args) {
new Frame();
}
1.4. ALGUNOS COMPONENTES SIMPLES
Todos los contenedores as como los componentes tienen propiedades que se pueden
modificar mediante los mtodos de la clase que corresponden, as como sus respectivos
constructores. Clase JLabelEs una etiqueta de texto que podemos colocar al lado de
cualquier componente para darle una indicacin al usuario de cul es la funcin de dicho
componente. Tambin se puede emplear a modo de ttulo.
JLabel label = new JLabel("1 x 7 = 7");
Clases JTextArea, JTextPane y JTextField Son componentes bsicos del Swing de Java y su
funcin principal es la de capturar texto ingresado desde teclado por el usuario. Clase
109

JTextField Est pensado para obtener texto del usuario, este teclear en l y cuando pulse
intro podremos disponer del texto que tecle. nicamente se puede recoger unalnea de
texto.
EJEMPLO:
public class Frame1 extends JFrame {public Frame1() {
setTitle("DATOS"); setSize(300, 200);
JLabel lbl1 = new JLabel("Nombre");
JTextField txt1 = new JTextField(18);
JLabel lbl2 = new JLabel("Edad");
JTextField txt2 = new JTextField(10);
Container contentpane = getContentPane();
JPanel panel = new JPanel();
panel.setBackground(Color.CYAN);
panel.add(lbl1); panel.add(txt1);
panel.add(lbl2); panel.add(txt2);
contentpane.add(panel);
setVisible(true);
}}
EJECUCIN Clase JPasswordField Al igual que los anteriores permite al Usuario ingresar
un texto que es reemplazado por un carcter que oculta lo que se escribe, por ejemplo: *.
Se emplea para pedirle passwords al usuario y evitar que puedan ser ledas por alguien.

Clase JButtonEsta clase nos permite crear botones, cuya accin al pulsar ser programado
conel manejo de eventos. Para crear un botn podemos utilizar los siguientes
constructores: JButton() Crea un botn sin etiqueta JButton(String label) Crea un
botn con una etiqueta de texto JButton t=new JButton(Derecha);
EJEMPLO:
public Frame2() {
setTitle("DATOS");
setSize(300, 200);
JLabel lbl1 = new JLabel("Nombre");
JTextField txt1 = new JTextField(18);
JLabel lbl2 = new JLabel("Edad");
JTextField txt2 = new JTextField(10);
Container contentpane = getContentPane();
JPanel panel = new JPanel(); panel.add(lbl1);
panel.add(txt1);
panel.add(lbl2);
panel.add(txt2);
panel.add(new JButton("Click aqu"));
contentpane.add(panel); setVisible(true);
}
EJERCICIO:Escriba 4 mtodos para cambiar el estado de un botn, una etiqueta y un
cuadro de texto
Clase JComboBox Permite seleccionar un objeto (opcin) de una lista que se visualiza al
dar click en la pestaa de este componente. Los constructores de la clase son:
JComboBox(ComboBoxModel amodel);
Requiere un objeto Modelo para el Combo
110

BoxJComboBox(Object [] items);
Crea un combo, cuyos items correspondern al arreglo de objetos.
JComboBox(Vector? items);
Crea un combo, cuyos items correspondern a los elementos del Vector.
EJEMPLO:
public class Selector extends JFrame {
public Selector() {
setTitle("Selector!!!");
setSize(300, 200);
String[] opciones = {"Arriba", "Abajo", "Derecha", "Izquierda", "Todas las direcciones"};
JComboBox cmbLista = new JComboBox(opciones);
Container contentpane = getContentPane();
JPanel panel = new JPanel();
panel.add(cmbLista); contentpane.add(panel);
setLocationRelativeTo(null); setVisible(true);
}}
Clase JCheckbox Se trata de un componente empleado para tomar informacin del
usuario sobre cosas del tipo s, no.Dos de los constructores de un JCheckBox son:
JCheckBox(String) Crea un JCheckBox con etiqueta o
JCheckBox(String,boolean) Crea un JCheckBox con etiqueta y aparece seleccionado
Clase JRadioButtonDos de los constructores de un JRadioButton son: o
JRadioButton (String) Crea un JRadioButton con etiqueta o
JRadioButton(String,boolean) Crea un JRadioButton con etiqueta y aparece seleccionado.
Para utilizar este componente debe ser aadido a un grupo de manera que permita
seleccionar una sola opcin entre las del grupo. Para ello se utiliza el componente
ButtonGroup.
Ejemplo:
ButtonGroup bg= new ButtonGroup();
JRadioButton rb1=new JRadioButton("Radio1");
JRadioButton rb2=new JRadioButton("Radio2");
bg.add(rb1); bg.add(rb2); ... panel.add(rb1);
panel.add(rb2); ... ...
Ejercicio:Crea una clase EjercicioSwing que extienda de JFrame y que contenga
loscomponentes de la siguiente figura. El tamao del Frame ser de (260 x 250).
10. 2. LAYOUT MANAGERS
2.1. Concepto El layout manager es el encargado de decidir en qu posiciones se
renderizarn los componentes, que tamao tendrn, que porcin del contenedor
abarcarn, etc. Un contenedor es un componente Java que puede contener otros
componentes. Si queremos cambiar el layout manager de un contenedor en un momento
dado, tan slo tendremos que llamar al mtodo:
contenedor.setLayout(LayoutManager layout);
Si en cualquier momento decidimos encargarnos nosotros mismos de la gestin
decomponentes tan slo tendremos que escribir:
contenedor.setLayout(null);
Cada componente de nuestro interfaz grfico tiene asignada una coordenadahorizontal,
una coordenada vertical, una longitud y una anchura determinadas. Estos valores sern
111

los que se utilizarn para renderizar el componente enpantalla.La clase


java.awt.Component nos ofrece una serie de mtodos para poder modificar los valores de
los
atributos
anteriores:
public
void
setSize(Dimension
size);
public
void
setBounds(Rectangle r);
2.2. Layout null Muchos deciden no utilizar layouts para ubicar los componentes de la
ventana, en este caso el Layout se establece a Null y en el cdigo se decide la posicin de
cada botn y qu tamao ocupa.contenedor.setLayout(null);
// Eliminamos el layout
contenedor.add (boton);
// Aadimos el botn
boton.setBounds (10,10,40,20);
// Botn en posicion 10,10 con ancho 40 pixels y alto 20 Esto, no es recomendable. Si se
expande la ventana los componentes seguirn en su sitio, no se expandirn con la
ventana.
Si cambiamos de sistema operativo, resolucin de pantalla o fuente de letra, los
componentes no se visualizarnestticamente bien.
2.3. FlowLayout Es el que tienen los paneles por defecto. Los objetos se van colocando en
filas enel mismo orden en que se aadieron al contenedor. Cuando se llena una fila se
pasa a la siguiente. Tiene tres posibles constructores: FlowLayout(); Crea el layout sin
aadirle los componentes.
FlowLayout(FlowLayout.LEFT[RIGTH][CENTER]); Indica la alineacin de los componentes: a
la izquierda, derecha o centro.
FlowLayout(FlowLayout.LEFT, gap_horizontal,gap_vertical); Adems de la alineacin de los
componentes indica un espaciado (gap) entre losdistintos componentes, de tal modo que
no aparecen unos junto a otros.
FlowLayout respeta siempre el tamao preferido de cada componente. Los componentes
de cada fila se encuentran equiespaciados por un espacio de 5puntos horizontal y
verticalmente. Primero se establece el layout a utilizar, luego se aaden los componentes
al
panel.contenedor.setLayout(new FlowLayout());
contenedor.add(boton);contenedor.add(textField);
contenedor.add(checkBox);
Ejemplo:
import javax.swing.*;
import java.awt.*;
class TestFlowLayout extends JFrame{ public static void main(String[] args) {
TestFlowLayout frame = new TestFlowLayout ();
JPanel panel = new JPanel();
JButton boton1 = new JButton("botn 1");
JButton boton2 = new JButton("Este es el botn 2");
JButton boton3 = new JButton("botn 3");
panel.add(boton1);
panel.add(boton2);
panel.add(boton3);
frame.setContentPane(panel);
frame.setSize(350, 150);
frame.setTitle("Prueba de FlowLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
112

frame.setVisible(true); } }
2.4. BorderLayout Este layout distribuye los componentes en cinco zonas
predeterminadas: son norte(NORTH), sur (SOUTH), este (EAST), oeste (WEST) y centro
(CENTER). Si no especificamos ninguna regin por defecto el componente se inserta en el
centro delcontenedor.
Posee dos contructores:
BorderLayout();BorderLayout(int gap_horizontal, int gap_vertical);
El segundo crear el layout dejando los espacios horizontales y verticales entre
susdistintas zonas. Al momento de aadir componentes se debe especificar en el mtodo
add la regin donde queremos aadir el componente:
panel.add(componente_a_aadir, BorderLayout.NORTH);
Ejemplo:
class TestBorderLayout extends JFrame{
public static void main(String[] args) {
TestBorderLayout frame = new TestBorderLayout ();
Container panel = frame.getContentPane();
JButton norte = new JButton("Norte");
JButton sur = new JButton("Sur");
JButton este = new JButton("Este");
JButton oeste = new JButton("Oeste");
JButton centro = new JButton("Centro");
panel.add(norte, BorderLayout.NORTH);
panel.add(sur, BorderLayout.SOUTH);
panel.add(este, BorderLayout.EAST);
panel.add(oeste, BorderLayout.WEST);
panel.add(centro, BorderLayout.CENTER);
frame.setSize(350, 250);
frame.setTitle("Prueba de BorderLayoutLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
} }}
2.5. GridLayout Distribuye los componentes de un contenedor en celdas y se ordenarn
en el orden como sean aadidas, de izquierda a derecha y de arriba hacia abajo.El
GridLayout es adecuado para hacer tableros, calculadoras en que todos losbotones son
iguales, etc.
14. Todas las cuadrculas sern del mismo tamao y crecern o se harn ms pequeas
hasta ocupar toda el rea del contenedor. Hay dos posiblesconstructores:GridLayout(int
filas,
int
columnas);GridLayout(int
columnas,
int
filas,
int
gap_horizontal,
intgat_vertical);Especifica espaciados verticales y horizontales entre las cuadrculas.
Ejemplo:
import javax.swing.*;
import java.awt.*;
class TestGridLayout extends JFrame{
public static void main(String[] args) {
113

TestGridLayout frame = new TestGridLayout();


Container container = frame.getContentPane();
int X = 3; int Y = 3; container.setLayout(new GridLayout(X, Y));
for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) {
container.add(new JButton(i + "x" + j));
}}
frame.setSize(350, 250);
frame.setTitle("Prueba de BorderLayoutLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
}}
2.6. GridBagLayout El GridBagLayout es de los layouts ms verstiles y complejos de
usar. Es como el GridLayout, pone los componentes en forma de matriz (cuadrcula), pero
permite que las celdas y los componentes en ellas tengan tamaos variados. Las celdas
se crean a medida que se agregan los componentes. Es posible hacer que un
componente ocupe varias celdas Un componente puede expandirse o no con su celda
Si no se expande, puede quedar en el centro de la celda o pegarse a sus bordes o
esquinas. Las columnas al igual que las filas pueden ensancharse o no al estirar la
ventana y la proporcin podemos decidirla GridBagConstraints es una clase en cuyos
atributos se guarda informacin de cmo y dnde aadir el componente.
GridBagConstraints.gridx nos dice la posicin x del componente, es decir, el nmero de
columna en la que est el componente, siendo la columna 0 la primera columna de la
izquierda. GridBagConstraints.gridy nos dice la posicin y del componente, es decir, el
nmero de fila en la que est el componente, siendo la fila 0 la primera fila de la parte de
arriba. c.gridx=1, c.gridy=0c.gridx=0, c.gridy=0c.gridx=0, c.gridy=1 c.gridx=1,
c.gridy=1 c.gridx=2, c.gridy=0
GridBagConstraints.gridwidth nos dice cuntas celdas en horizontal debe ocupar el
componente. El ancho del componente. GridBagConstraints.gridheight nos dice cuantas
celdas en vertical debe ocupar el componente. El alto del componente. Su valor puede
ser: Un nmero cardinal, en este caso indica exactamente el nmero de filas o
columnas que ocupar el componente.
GridBagConstraints.RELATIVE, indica que el componente ocupar el espacio disponible
desde la fila o columna actual hasta la ltima fila o columna disponibles.
GridBagConstraints.REMAINDER, indica que el componente es el ltimo de la fila actual o
columna actual. c.gridwidth=GridBagCostraints.RELATIVE
c.gridwidth=GridBagCostraints.REMAINDER
c.gridheigth=1
c.gridheigth=1
c.gridwidth=1
c.gridheigth=1c.gridwidth=GridBagCostraints.RELATIVE
c.gridheigth=GridBagConstraints.RELATIVE
c.gridwidth=GridBagCostraints.REMAINDER
c.gridheigth=GridBagConstraints.REMAINDER
c.gridwidth=GridBagCostraints.REMAINDER
c.gridheigth=GridBagConstraints.RELATIVE
Algunas constantes de esta clase son: Anchor establece la alineacin del componente, se
utiliza cuando el ste es ms pequeo que el rea utilizada: NORTH, SOUTH, EAST,
WEAST, NORTHWEST, SOUTHWEST, NORTHEAST, SOUTHEAST y CENTER.
Fill establece el relleno de la celda: HORIZONTAL, VERTICAL, BOTH, NONEEn este caso las
celdas ocupan todo el contenedor, pero eso es debido a que se hautilizado los atributos
weightx y weighty.weightx y weightyLos atributos weightx y weighty especifican el
114

porcentaje de espacio libre queocupar una celda determinada.En el ejemplo anterior si


no utilizamos estos atributos tendramos:
Este espacio libre (flechas verdes) se dividir entre todas las celdas queespecifiquen
valores dentro de los atributos weightx y weighty. La forma deespecificar el espacio que
quiere ocupar cada componente es mediante un nmeroentre 0.0 y 1.0. Este nmero
representa al porcentaje de espacio libre que ocuparcada celda.InsetsEl atributo insets
es un objeto de la clase java.awt.Insets cuyo constructor es:Insets(int top, int left, int
bottom, int right)
Los parmetros del constructor especifican el espacio que se dejar de mrgen.Veamos
un ejemplo:
Ejemplo:
Frame que distribuye los siguientes componentes:
public class TestGridBagLayout extends JFrame{
public static void main(String[] args) {
TestGridBagLayout f=new TestGridBagLayout();
Container container = f.getContentPane();
container.setLayout(new GridBagLayout());
((JPanel) container).setBorder( BorderFactory.createTitledBorder("Entrada al sistema"));
GridBagConstraints c = new GridBagConstraints();
c.weightx = 0.4; c.weighty = 1.0; c.gridwidth = GridBagConstraints.RELATIVE;
c.gridheight = GridBagConstraints.RELATIVE;
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(2, 5, 2, 0); container.add(new JLabel("Usuario"), c);
//Se debe definir los parmetros para cada uno de los componentes.
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = GridBagConstraints.RELATIVE;
c.weightx = 1.0; c.insets = new Insets(2, 0, 2, 5);
container.add(new JTextField(), c); c.gridwidth = GridBagConstraints.RELATIVE;
c.gridheight = GridBagConstraints.REMAINDER;
c.weightx = 0.4; c.insets = new Insets(2, 5, 2, 0);
container.add(new JLabel("Contrasea"), c);
c.gridwidth
=
GridBagConstraints.REMAINDER;
c.gridheight
=
GridBagConstraints.REMAINDER;
c.weightx = 1.0; c.insets = new Insets(2, 0, 2, 5);
container.add(new JTextField(), c);
f.setSize(220, 110);
f.setTitle("Login"); f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}}
Resultado:
2.7. BoxLayout Este layout manager es uno de los ms sencillos y de los ms tiles. Aqu
los componentes son agrupados horizontal o verticalmente dentro del contenedor que los
contiene. Los componentes no se solapan de ningn modo. La anidacin de paneles
utilizando este layout manager nos puede permitir crear interfaces muycomplejos como
nos permite GridBagLayout pero a costa de la creacin de objetos pesados como son
paneles.El constructor de BoxLayout es muy simple:public BoxLayout(Container objetivo,
115

int eje);Donde el parmetro entero eje puede tomar los valores: X_AXIS, los
componentes se organizan de izquierda a derecha y en horizontal. Y_AXIS, los
componentes se organizan de arriba a abajo y en vertical. LINE_AXIS, los componentes
se organizan como si estuviesen en una lnea. Para ello se tiene en cuenta la propiedad
ComponentOrientation del contenedor.
Si esta propiedad es horizontal entonces los componentes se organizarn
horizontalmente y adems segn su valor lo harn de izquierda a derecha o de derecha a
izquierda. En otro caso se organizarn verticalmente de arriba a abajo. PAGE_AXIS, los
componentes se organizan como si estuvieran en una pgina. Para ello se tiene en cuenta
la propiedad ComponentOrientation del contenedor. Los componentes se organizan en el
orden en el que se aaden al contenedor.En el caso de organizacin horizontal, BoxLayout
intentar que todos los componentes del contenedor tengan la misma altura, siendo esta
la mxima de loselementos del contenedor. En caso de que no sea posible, BoxLayout
intentaralinearlos a todos horizontalmente de modo que sus centros coincidan en una
lnea horizontal imaginaria que los atraviese, de manera similar, si la organizacin es
vertical.
A menudo, en lugar de utilizar BoxLayout directamente, se utiliza la clase Box quees un
contenedor ligero que tiene como layout manager un BoxLayout y que ofrecemtodos que
hacen que su manejo sea muy sencillo.
EJEMPLO:
import java.awt.*;
import javax.swing.*;
public class TestBoxLayout extends JFrame {
public static void main(String[] args) {
TestBoxLayout f = new TestBoxLayout();
Container container = f.getContentPane();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
((JPanel) container).setBorder( BorderFactory.createTitledBorder("Demo BoxLayout"));
JPanel
panel1
=
new
JPanel();
panel1.setBorder(BorderFactory.createTitledBorder("Panel1"));
JPanel panel2 = new JPanel();
panel2.setBorder(BorderFactory.createTitledBorder("Panel2"));
panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.Y_AXIS));
for (int i = 0; i < 3; i++) { panel1.add(new JButton("Botn nmero " + i));
panel2.add(new JButton("Botn nmero " + i));
}
container.add(panel1);
container.add(panel2);
f.setSize(285, 300);
f.setTitle("Demo BoxLayout");
f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}}
2.8. SpringLayout Este layout manager est nicamente disponible a partir de la versin
1.4 del JDK.SpringLayout define los componentes que estarn dentro del interfaz y la
relacin entre estos componentes, es decir, el espacio que habr entre ellos. SpringLayout
116

intentar respetar siempre que pueda el tamao preferido de los componentes. El espacio
entre los componentes se define utilizando objetos Spring. Cada objetoSpring tiene cuatro
propiedades, sus tamaos mximo, mnimo y preferido junto con su tamao actual. (x, y,
width, height)Todos estos objetos Spring se acumulan formando un conjunto de
restricciones que estarn en un objeto de tipo SpringLayout.Constraints.Para crear un
objeto Spring:Spring.constant(min, pref, max);Spring.constant(int valor); El mtodo para
ubicar un componente aplicando constraint tespecto de otro:putConstraint(borde,
componente, constraint, borde, componenteRelativo);
Ejemplo:
public class TestSpringLayout extends JFrame {
public static void main(String[] args) {
TestSpringLayout f=new TestSpringLayout();
SpringLayout sl=new SpringLayout();
Container container = f.getContentPane();
container.setLayout(sl);
((JPanel)container).setBorder(BorderFactory.createTitledBorder( "Entrada al sistema"));
JLabel lblUsuario =new JLabel("Usuario");
JLabel lblContrasea=new JLabel("Contrasea");
JTextField txtUsuario=new JTextField(10);
JTextField txtContrasea=new JTextField(10);
container.add(lblUsuario);
container.add(txtUsuario);
container.add(lblContrasea);
container.add(txtContrasea);
sl.putConstraint(SpringLayout.WEST,
lblUsuario,
Spring.constant(30),SpringLayout.WEST,container); sl.putConstraint(SpringLayout.NORTH,
lblUsuario,
Spring.constant(20),SpringLayout.NORTH,container);
sl.putConstraint(SpringLayout.WEST,txtUsuario,
Spring.constant(35),SpringLayout.EAST,lblUsuario); sl.putConstraint(SpringLayout.NORTH,
txtUsuario,
Spring.constant(20),SpringLayout.NORTH,container);
sl.putConstraint(SpringLayout.WEST,
lblContrasea,
Spring.constant(30),SpringLayout.WEST,container); sl.putConstraint(SpringLayout.NORTH,
lblContrasea,
Spring.constant(25),SpringLayout.NORTH,lblUsuario);
sl.putConstraint(SpringLayout.WEST,txtContrasea,
Spring.constant(15),SpringLayout.EAST,lblContrasea);
sl.putConstraint(SpringLayout.NORTH,
txtContrasea,
Spring.constant(25),SpringLayout.NORTH,txtUsuario);
f.setSize(250,
150);
f.setTitle("Login");
f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}}
EJERCICIO:Disee la siguiente pantalla utilizando el Layout ms indicado para la ubicacin
delos componentes en el Frame
25. 3. ALGUNOS COMPONENTES COMPLEJOS
3.1. Componentes contenedores de otros. Clase JMenuBarEs una barra de mens, en
ella se pueden aadir los siguientes componentes:Clase JMenu: Es una opcin de la cual
117

se pueden desplegar mas opciones.Clase JMenuItem: Es una opcin final (no desplega
mas opciones) JMenu JMenuBar JMenuItem

EJEMPLO:
public class VentanaMenu extends JFrame{
public JMenuBar barraMenu=new JMenuBar();
public VentanaMenu(){ super("Test Menu");
setSize(300,200); agregarComponentes();
}
public void agregarComponentes(){ JMenu mnArchivo=new JMenu("Archivo");
mnArchivo.add(new JMenuItem("Nuevo"));
mnArchivo.add(new
JMenuItem("Guardar",new
ImageIcon(getClass().getResource("zip.gif")))); mnArchivo.add(new JMenuItem("Abrir"));
mnArchivo.add(new JMenuItem("Cerrar"));
barraMenu.add(mnArchivo);
JMenu mnEditar=new JMenu("Editar");
JMenu mnAyuda=new JMenu("Ayuda"); barraMenu.add(mnEditar);
barraMenu.add(mnAyuda);
BorderLayout bl=new BorderLayout();
this.getContentPane().setLayout(bl);
this.getContentPane().add(barraMenu,BorderLayout.NORTH);
}
public static void main(String[] args) {
new VentanaMenu().setVisible(true);
}}
RESULTADO:Ejercicio: Modifique la clase anterior para: Agregar al Menu Archivo el menu
Guardar Como y a ste los tems: Imagen, Texto, Articulo Completo. Agregar en el Menu
Editar los tems: Deshacer, Rehacer, Seleccionar Todo, Buscar. Agregar una imagen en
los Menus de la barra principal. Clase JScrollPaneEs un panel que permite visualizar un
componente de un tamao mayor que el disponible, mediante el uso de barras de
desplazamiento. Como su nombre lo indica, funciona como un contenedor, de manera que
podemos agregar un componente que requiera mayor espacio en el Frame.
JLabel
imagen=new
JLabel(new
ImageIcon(getClass().getResource("/imagenes/imagen1.jpg")));
JScrollPane panel=new JScrollPane(imagen);
Clase JSplitPane Permite visualizar dos componentes, uno a cada lado, con la posibilidad
demodificar la cantidad de espacio otorgado a cada uno. Se puede agregar un contenedor
como un JPanel en cada lado del Split y este a su vez contener ms componentes.
Adems se puede modificar una propiedad que indica la disposicin de los componentes:
horizontal o vertical.
//espacio del primer componente con respecto del segundo
split.setDividerLocation(150);
//separacin
entre
componentes
del
Splitsplit.setDividerSize(20);
//cambiando el componente de la izquierda y derecha
split.setLeftComponent(componenteIzquierda);
split.setRightComponent(componenteDerecha);
118

EJERCICIO:SPLITPANE Y SCROLLPANE Ubicar el primer componente con mayor ventaja que


el segundo, con respecto altamao del contenedor principal y una divisin de 20pix.
Clase JTabbedPane Permite definir varias hojas con pestaas, que pueden contener otros
componentes. El componente bsico de cada hoja debe ser un Panel que es el que agrupe
el resto de componentes. Para agregar ms hojas basta con aadir un panel al
TabbedPane.
Ejemplo: JTabbedPane tabbed=new JTabbedPane();
tabbed.add("Tabbed 1", new JPanel());
tabbed.add("Tabbed 2",new JPanel());
3.2. COMPONENTES CON MODELO DE DATOS. Los componentes que permiten mostrar un
listado o un conjunto de objetos sepueden crear a partir de un modelo de datos. Por
ejemplo un componente sencillo como el JComboBox contiene un arreglo de objetos.
3.2.1. JLIST Un componente JList permite administrar una lista de elementos de tipo
Object con una representacin en String Los constructores de la clase JList son: JList()
JList(ListModel dataModel) JList(Object[ ] listData) JList(Vector ? listData) El
segundo constructor recibe un objeto tipo ListModel, como sta es una
interfaceutilizaremos una clase que la implementa:
DefaultListModel
DefaultList Model modeloLista=new DefaultListModel();
Un objeto de esta clase puede implementar el mtodo
addElement(Object o).modeloLista.addElement(Elemento1);
//Object de tipo
String.modeloLista.addElement(Elemento2);
JList lista=new JList(modeloLista);
// Se crea un JList con el modelo de elementos.
Ejemplo:
public class Lista extends JFrame{
private JList listaCursos;
private DefaultListModel modeloListaCursos;
public Lista() { agregarComponentes();
setTitle("CURSOS");
setContentPane(p);
setSize(250, 200)}public void agregarComponentes() {
modeloListaCursos=new DefaultListModel();
modeloListaCursos.addElement("C++");
modeloListaCursos.addElement("Java");
modeloListaCursos.addElement("OpenOffice");
modeloListaCursos.addElement("Linux");
modeloListaCursos.addElement("Phyton");
listaCursos=new JList(modeloListaCursos);
JPanel p=new JPanel();
p.setBorder(BorderFactory.createTitledBorder("Lista de Cursos"));
p.add(listaCursos);
}
public static void main(String []args){
119

new Lista().setVisible(true);
}}
Resultado:
EJERCICIO Crear un Proyecto denominado Componentes Avanzados y dentro del paquete
ventanas disear un clase VentanaPrincipal que extienda de JFrame y que tngalos
constructores
necesarios
para
modificar
sus
propiedades.Crear
una
clase
ComponenteLista que permita utilizar la VentanaPrincipal para aadir un JList similar al
ejemplo, que contenga la lista de 5 estudiantes del saln.
3.2.2. JTABLE JTable es uno de los componentes con APIs ms extensas y tambin son
complejos, esa complejidad le permite ser ms personalizable y potente. Los
constructores que proporciona esta clase son: JTable()
JTable(int numRows, int numColumns)
JTable(Object[][] rowData, Object[] columnNames)
JTable(TableModel dm)
JTable(TableModel dm, TableColumnModel cm)
JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm)
JTable(Vector rowData, Vector columnNames)
El primer constructor permite crear un JTable con las propiedades por defecto, elsegundo
crea la tabla como una matrz de numRows x numColumns.Vamos a ver un ejemplo
utilizando el constructor, que permite crear una tabla conuna matriz de datos (rowData) y
los nombres de las columnas contenidos en unarray de String.Nuestro primer ejemplo
tendr las siguientes columnas:
String[] columnNames = {"Nombre", "Apellido", "Pasatiempo", "Aos de Practica",
"Soltero(a)"};
Y utilizaremos el siguiente array para su contenido:
Object[][] data = { {"Maria", "Castro", "Esquiar", new Integer(5), newBoolean(false)},
{"Lucas", "Herrera", "Patinar", new Integer(3), newBoolean(true)}, {"Kthya", "Espinoza",
"Escalar", new Integer(2), newBoolean(false)}, {"Marco", "Molina", "Correr", new
Integer(7),
newBoolean(true)},
{"Angela",
"Daz",
"Nadar",
new
Integer(4),
newBoolean(false)}};La creacin de una tabla con estos datos sera:JTable table = new
JTable(data, columnNames);
Ejemplo:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;public class
EjemploTabla1 extends JFrame{
public EjemploTabla1() {
super("Ejemplo 1");
//array bidimensional de objetos con los datos de la tabla
Object[][] data = { {"Maria", "Castro", "Esquiar", new Integer(5), new Boolean(false)},
{"Lucas", "Herrera", "Patinar", new Integer(3), new Boolean(true)}, {"Kthya", "Espinoza",
"Escalar", new Integer(2), new Boolean(false)}, {"Marco", "Molina", "Correr", new
120

Integer(7), new Boolean(true)}, {"Angela", "Daz", "Nadar", new Integer(4), new


Boolean(false)}};
//array de Strings con los ttulos de las columnas String[] columnNames = {"Nombre",
"Apellido", "Pasatiempo", "Aos de Practica", "Soltero(a)"};
//se crea la Tabla
JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
//Creamos un JscrollPane y le agregamos la
JScrollPane scrollPane = new JScrollPane(table);
//Agregamos el JScrollPane al contenedor
getContentPane().add(scrollPane, BorderLayout.CENTER);
}
public static void main(String[] args) {
EjemploTabla1 frame = new EjemploTabla1();
frame.pack(); frame.setVisible(true);
}}
Modelo de tabla Los modelos de tabla son objetos que implementan la interface
TableModel; a travs de ellos es posible personalizar mucho ms y mejor el
comportamiento delos componentes JTable, permitiendo utilizar al mximo sus
potencialidades.Todas las tablas cuentan con un modelo de tabla, aunque en el ejemplo 1
no sehaya especificado, existe uno por omisinLa clase AbstractTableModel es la que
implementa directamente ala interface TableModel, aunque es esta clase la que se
recomienda extender para utilizarla como modelo de tabla, existe un modelo de tabla
predeterminado quefacilita mucho el trabajo con tablas. Este modelo predeterminado es
la clase
DefaultTableModel
DefaultTableModel
Esta clase tiene el siguiente diagrama de herencia:
java.lang.Object
|
+-javax.swing.table.AbstractTableModel
|
+javax.swing.table.DefautTableModel
Nuevamente, antes de comenzar a utilizar esta clase, veremos cuales sonlos
constructores con que cuenta: DefaultTableModel()
DefaultTableModel(int numRows, int numColumns)
DefaultTableModel(Object[][] data, Object[] columnNames)
DefaultTableModel(Object[] columnNames, int numRows)
DefaultTableModel(Vector columnNames, int numRows)
DefaultTableModel(Vector data, Vector columNames)
Utilizaremos el constructor que nos permite crear un DefaultTableModel, a partir de los
datos con que ya contamos del ejemplo anterior: Por lo tanto, el constructor queda as:
DefaultTableModel dtm= new DefaultTableModel(data, columnNames);
Despues de haber creado el modelo de tabla, dtm en el ejemplo, se creala tabla con el
constructor correspondiente:
JTable table = new JTable(dtm);
Una vez hecho esto, cualquier modificacin que se realice sobre el modelo detabla se
reflejar directamente en la tabla. Agregar una columna:
String[] newColumn= {"Contabilidad", "Informatica", "Medicina", "Musica", "Diseo"};
dtm.addColumn("Carrera",newColumn);
Agregar una fila: Object[] newRow={"Jose", "Ordez", "Tenis", new Integer(5), new
Boolean(false), "Pera"}; dtm.addRow(newRow);
121

Modificar una celda en especial, en este ejemplo la celda ubicada en la columna 1, fila 1:
dtm.setValueAt("Catherine", 1, 1);
Puedes revisar los mtodos que proporciona la clase DefaultTableModel paraconocer qu
otras cosas puedes realizar con ella.
Ejemplo
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class EjemploTabla2 extends JFrame {
public EjemploTabla2() { super("Ejemplo 2");
//array bidimencional de objetos con los datos de la tabla
Object[][] data = { {"Maria","Castro", "Esquiar", new Integer(5), new Boolean(false)},
{"Lucas", "Herrera", "Patinar", new Integer(3), new Boolean(true)}, {"Kthya","Espinoza",
"Escalar", new Integer(2), new Boolean(false)}, {"Marco", "Molina", "Correr", new
Integer(7), new Boolean(true)}, {"Angela","Daz", "Nadar", new Integer(4), new
Boolean(false)}};
//array de Strings con los ttulos de las columnas
String[] columnNames = {"Nombre", "Apellido", "Pasatiempo", "Aos de Practica",
"Soltero(a)"};
//creamos el Modelo de la tabla con los datos anteriores
DefaultTableModel dtm= new DefaultTableModel(data, columnNames);
//se crea la Tabla con el modelo
DefaultTableModel final JTable tabla = new JTable(dtm);
// una vez creada la tabla con su modelo // podemos agregar columnas
String[] newColumn= {"Contabilidad", "Informatica", "Medicina", "Musica", "Diseo" };
dtm.addColumn("Carrera",newColumn);
//filas
Object[] newRow={"Jos", "Ordez", "Tenis", new Integer(5), new Boolean(false),
"Informatica"}; dtm.addRow(newRow);
//o modificar una celda en especifico
dtm.setValueAt("Sofa", 1, 1);
//se define el tamao
tabla.setPreferredScrollableViewportSize(new Dimension(500, 70));
//Creamos un JscrollPane y le agregamos la JTable
JScrollPane scrollPane = new JScrollPane(tabla);
//Agregamos el JScrollPane al contenedor
getContentPane().add(scrollPane, BorderLayout.CENTER);
}
public static void main(String[] args) {
EjemploTabla2 frame = new EjemploTabla2();
frame.pack();
frame.setVisible(true);
}}
AbstractTableModel Con esta clase es posible implementar, de una manera ms
completa y eficiente,los mtodos necesarios para crear un modelo de tabla.Para crear un
modelo de tabla personalizado, lo primero que necesitamoses extender la clase
122

AbstractTableModel. class MyTableModel extends AbstractTableModel { ..... }Como es una


clase Abstracta debemos de implementar los 3 mtodos siguientes:
class MyTableModel extends AbstractTableModel {
public int getRowCount(){ ... }
public int getColumnCount(){ ... }
public Object getValueAt(int row, int column){ ... }
}
Con la implementacin de los mtodos anteriores, las celdas de la tabla NO sern
editables y NO se podrn modificar los valores de cada una de ellas. Si deseamos tener un
mecanismo para modificar los valores de las celdas dela tabla, tenemos que sobrescribir
el mtodo setValueAt de la
clase AbstractTableModel:
class MyTableModel extends AbstractTableModel { ... ...
public void setValueAt(Object value, int row, int col) { ... }
}
Y, si la modificacin de los valores de las celdas, se hace directamente sobre
ellas,necesitamos indicar a nuestro modelo de tabla que las celdas de la tabla
serneditables, esto se hace sobrescribiendo el mtodo
isCellEditable:
class MyTableModel extends AbstractTableModel { ...
public boolean isCellEditable(int row, int col) { ... }
}
Ya lo nico que hara falta sera agregar los nombres de las columnas de nuestra tabla y
definir su contenido inicial:
class MyTableModel extends AbstractTableModel {
final String[] columnNames = { ... }
final Object[][] data = { ... } ...
}
JTable invoca un mtodo del modelo de tabla para determinar eleditor/renderer
predeterminado que utilizar para mostrar el valor de cada celda. Por ejemplo para celdas
con valores booleanos utilizar check boxs; este mtodoes: getColumnClass, y tambin es
recomendable implementarlo:
class MyTableModel extends AbstractTableModel { ...
public Class getColumnClass(int c) { ... }
}
EjercicioCrear un proyecto ProyectoTablaSwing dentro del cual tendremos el
paquetemodelo con las clases ModeloTablaEstudiante y Estudiante: Estudiante - id: int nombre: String - apellido: String - carrera: String - modulo: String - paralelo: String promedio: doubleAdicionalmente un paquete presentacion contiene la clase
VentanaEstudiantesque ser el frame con la tabla de estudiantes. Disea una clase
Ejecutable que permita crear 5 estudiantes y almacenarlos enun Vector de manera que se
pueda crear el Modelo de la tabla con estos datos. JTreeAl igual que JTable su creacin
se basa en un modelo que permite definir el nodo raz y los nodos hoja del componente.
Algunos de sus constructores son:
123

JTree()
JTree(Object[] value) Retorna un JTree cuyos nodos hoja sern los objetos contenidos en el
Array value. JTree(TreeModel newModel) Crea una instancia de JTree en base al modelo
del parmetro
JTree(TreeNode root) Crea un JTree con un nodo raz TreeNode.
JTree(Vector<?> value) Crea un JTree con cada elemento especificado en el Vector como
hijos de un nodo raz que no es mostrado. TreeNode es la interfaz que permite generar los
nodos del rbol, sin embargo porsu naturaleza no podemos crear objetos de ella.
Existen algunas clases que implementan esta interfaz y de las cuales podemos hacer
uso.
DefaultMutableTreeNode Esta clase permite crear objetos TreeNode para aadirlos a un
JTree; como es necesario tener un Nodo principal crearemos primeramente ste y
luegoaadiremos sus nodos hoja utilizando el constructor que recibe como parmetro
elnombre del nodo:
DefaultMutableTreeNode
nodoPrincipal=new DefaultMutableTreeNode("Nodo Principal");
DefaultMutableTreeNode nodo1=new DefaultMutableTreeNode("Nodo 1");
DefaultMutableTreeNode nodoSub1=new DefaultMutableTreeNode("Nodo hijo 1");
nodo1.add(nodoSub1);
nodoPrincipal.add(nodo1);
Ahora crearemos el rbol con el nodo principal, utilizando el cuarto constructor delos
antes mencionados:JTree arbol=new JTree(nodoPrincipal);EJERCICIOPara el ejercicio
utilizaremos el Proyecto ComponentesAvanzados de modo quepodamos reutilizar la clase
VentanaPrincipal para crear el frame que contendrun rbol con la clasificacin de los
animales.
4. EVENTOS
4.1. Qu es un evento? Todos los sistemas operativos estn constantemente atendiendo
a los eventos generados por los usuarios. Estos eventos pueden ser: pulsar una tecla,
mover elratn, hacer clic con el ratn, pulsar el ratn sobre un botn o men (Java
distingueentre simplemente pulsar el ratn en un sitio cualquiera o hacerlo, por ejemplo,
enun botn). El sistema operativo notifica a las aplicaciones que estn ocurriendo estos
eventos, y ellas deciden si han de responder o no de algn modo a este evento.
4.2. Gestin de EventosPara hacer que el manejador escuche los eventos de otro objeto
se emplea elmtodo add[nombre_evento]Listener.
Ejemplo:
frame.addMouseListener(manejador);
Este mtodo permite registrar eventos del ratn asociados a un objeto frame. Esto se
denomina Registro de Receptores especficos para los eventos. El objetofuente utiliza esta
lista para notificar a cada receptor que ha sucedido un evento delos que controla.Hay
algunas clases de eventos que involucran a ms de un evento, tal es el casodel ratn. Por
tanto, la clase que implementa el manejador de eventos del ratndebe sobreescribir
todos los mtodos declarados en la interfaz MouseListener,tales como mousePressed,
mouseReleased, mouseClicked, mouseMoved y otros.
Para facilitar el manejo de estos eventos, se han definido un nmero de clases
intermedias, conocidas como clases adaptadores (Adapters), para no tener que
124

sobreescribir todos los mtodos de la interfaz cuando se requiere controlar un solotipo de


evento. De esta manera podemos definir dos caminos para acceder a los Oyentes de
loseventos para un componente especfico: Implementando la interfaz, lo cual implica
sobreescribir todos sus mtodos.
public class EventoMouse implements MouseListener{...
Extendiendo una clase adaptadora, con lo cual se sobreescriben solo los mtodos
deseados. public class EventoMouse extends MouseAdapter{...
Los eventos estn agrupados de acuerdo a su naturaleza en los siguientes grupos:
ActionListener: acciones sobre componentes.
WindowListener: cierre o manipulacin una ventana (Frame/Dialog).
MouseListener: presin de un botn del mouse mientras el cursor est sobre el
componente. MouseMotionListener: movimiento del mouse sobre un componente.
ComponentListener: visibilidad del componente.
FocusListener: obtencin del foco del teclado.
ListSelectionListener: seleccin de tems dentro de una lista. A continuacin en la
siguiente se lista las principales interfaces junto a susrespectivas clases Adapter y los
mtodos que poseen para los componentes:
Listener interface y Adapter Metodos ActionListener
actionPerformed(ActionEvent)AdjustmentListener
adjustmentValueChanged(AdjustmentEvent)ComponentListener
componentHidden(ComponentEvent)ComponentAdapter
componentShown(ComponentEvent)
componentMoved(ComponentEvent)
componentResized(ComponentEvent)ContainerListener
componentAdded(ContainerEvent)ContainerAdapter
componentRemoved(ContainerEvent)FocusListener
focusGained(FocusEvent)FocusAdapter focusLost(FocusEvent)KeyListener
keyPressed(KeyEvent)KeyAdapter
keyReleased(KeyEvent)
keyTyped(KeyEvent)MouseListener
mouseClicked(MouseEvent)MouseAdapter
mouseEntered(MouseEvent)
mouseExited(MouseEvent)
mousePressed(MouseEvent)
mouseReleased(MouseEvent)MouseMotionListener
mouseDragged(MouseEvent)MouseMotionAdapter
mouseMoved(MouseEvent)WindowListener
windowOpened(WindowEvent)WindowAdapter
windowClosing(WindowEvent)
windowClosed(WindowEvent)
windowActivated(WindowEvent)
windowDeactivated(WindowEvent)
windowIconified(WindowEvent)
windowDeiconified(WindowEvent)ItemListener
itemStateChanged(ItemEvent)ListSelectionListener valueChanged(ListSelectionEvent)
Ejemplo1. Vamos a trabajar con un evento que permite finalizar la ejecucin del programa
al momento de cerrar la VentanaBase, ya que de otro modo seguir ejecutndose.
public class VentanaBase extends JFrame {
125

public VentanaBase() {
setTitle("Evento WindowClosing");
setSize(new Dimension(300, 200));
this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent
e) { JOptionPane.showMessageDialog(null,"El programa finalizara cuando pulse Aceptar");
System.exit(0);
} });
}
public static void main(String[] args) {
new VentanaBase().setVisible(true);
}}
En el ejemplo aadimos un escuchador WindowListener al frame e implementamosel
mtodo windowClosing.2. Aadimos a la VentanaBase un botn salir para cerrar la
Ventana mostrando un cuadro de confirmacin.
salir.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int opc=JOptionPane.showConfirmDialog(null,"Esta seguro de cerrar la Ventana");
if(opc==0){ System.exit(0); }
}
}
);
Ejemplo
ItemListener ItemListener es un manejador que escucha todos los eventos relacionados
con laseleccin o cambio de algn tem en un componente que implica seleccin.Vamos a
crear una clase JFrame como la siguiente: Para manejar los eventos generados a partir de
la seleccin de los ChekBox,construiremos una clase que implemente la interfaz
ItemListener de manera quepodamos sobreescribir el mtodo itemStateChanged
(ItemEvent e)Trabajamos con la clase Font para cambiar el estilo de la Fuente del TextField
private class CheckBoxListener implements ItemListener {
private int valBold = Font.PLAIN;
private int valItalic = Font.PLAIN;
@Override public void itemStateChanged(ItemEvent e) { if (e.getSource() == bold) {
if (e.getStateChange() == ItemEvent.SELECTED) {
valBold = Font.BOLD;
}
else {
valBold = Font.PLAIN;
}
}
if (e.getSource() == italic) {
if (e.getStateChange() == ItemEvent.SELECTED) {
valItalic = Font.ITALIC; } else { valItalic = Font.PLAIN;
} } ... ...
}}
126

Aadimos el escuchador a los componentes del Frame


(CheckBox):JCheckBox bold = new JCheckBox("Bold");
JCheckBox italic = new JCheckBox("Italic");
CheckBoxListener handler = new CheckBoxListener();
bold.addItemListener(handler);
bold.addItemListener(handler);
Es el mismo objeto listener que aadimos a todos los CheckBox ya que es un soloobjeto el
que va a recibir los eventos y va a realizar los cambios seleccionados.
Ejemplo:
MouseMotionListenerpublic class Ventana extends JFrame{
public Ventana(){ setTitle("Evento Mouse");
setSize(new Dimension(250, 150));
setLocationRelativeTo(null);
final JPanel panel1=new JPanel();
panel1.setBackground(Color.gray);
final JButton boton =new JButton("Boton");
boton.addMouseMotionListener(new MouseMotionAdapter() {
public
void
mouseMoved(MouseEvent
e){
Cursor(Cursor.MOVE_CURSOR));
}
}
);
panel1.add(boton);
panel1.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseMoved(MouseEvent e){
panel1.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
}
);
this.add(panel1); this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){ System.exit(0);
}
}
);
setVisible(true);
}}

boton.setCursor(new

5. GRFICOS EN SWING
Todos los contenedores en swing permiten ser redibujados (repaint) en tiempo de
ejecucin, es decir aadir algn componente modificar posiciones, pintar sobre el
contenedor, etc. Esto se debe a que un contenedor swing deriva dejava.awt.Container, y
de esta manera a sus mtodos.Uno de ellos es el mtodopaint(Graphics g)dibuja un
grfico (Graphics) en el contenedor.
La clase Graphics permite disearalgunas formas como: Lineas
drawLine(int x1, int y1, int x2, int y2) Dibuja una lnea usando el color actual entre los
puntos (x1, y1) y (x2, y2) en el sistema de coordenadas del grafico
Circulos
127

drawOval(int x, int y, int width, int height) Dibuja un valo en la posicin x, y, el ancho y
alto del crculo. Polgono drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
Dibuja un poligono cerrado definido por arreglos de (x, y) coordenadas.
Rectngulo
drawRect(int x, int y, int width, int height)
Dibuja un rectngulo en (x, y) con su tamao width, height.
drawString(String str, int x, int y)
Dibuja el texto del String srt usando el contexto actual del grfico y el actual color de
fuente. Para dibujar formas con relleno usa los mtodos:
fill3DRect(int x, int y, int width, int height, boolean raised)
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
fillOval(int x, int y, int width, int height) fillPolygon(int[] xPoints, int[] yPoints, int nPoints)

fillRect(int x, int y, int width, int height)


fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
Ejemplo:g.fillOval(10,5, 4, 4); dibujar un valo relleno en un cuadrado de 4x4 en la
posicin (10,5) del contedordonde se dibuja.
EJEMPLO JFrame Pintor:
public class Pintor extends JFrame {
private int cuentaPuntos = 0;
private JLabel j=new JLabel("Van: "+cuentaPuntos+" puntos");
// arreglo de 2000 referencias a
java.awt.Pointprivate Point puntos[] = new Point[ 2000 ];
// configurar GUI y registrar manejador de eventos de
ratnpublic Pintor() {super( "Un programa simple de dibujo" );
//crear una etiqueta y colocarla en la parte
SOUTH del BorderLayoutgetContentPane().add( new JLabel( "Arrastre el ratn para
dibujar" ),BorderLayout.SOUTH );
getContentPane().add( j,BorderLayout.NORTH );
addMouseMotionListener( new MouseMotionAdapter() {
// clase interna annima // almacenar coordenadas de arrastre y llamar a
repaint public void mouseDragged( MouseEvent evento ) {
if ( cuentaPuntos < puntos.length ) {
puntos[ cuentaPuntos ] = evento.getPoint(); ++cuentaPuntos; repaint();
j.setText("Van: "+cuentaPuntos+" puntos, le quedan:" +(2000-cuentaPuntos)+"puntos");
}}}
// fin de la clase interna annima );
// fin de la llamada a
addMouseMotionListener setSize( 400, 200 );
setVisible( true );
}
// fin del constructor de Pintor// dibujar valo en un cuadro delimitador de 4x4 en
ubicacin especifica
public void paint( Graphics g ){ super.paint( g );
// borra el rea de dibujo
for ( int i = 0; i < puntos.length && puntos[ i ] != null; i++ )
g.fillOval( puntos[ i ].x, puntos[ i ].y, 4, 4 );
}
128

public static void main( String args[] ) {


Pintor aplicacion = new Pintor();
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}}
6. GENERADOR DE INTERFACES DE NETBEANS El IDE
Netbeans permite crear interfaces grficas de manera visual, es decir agregar a un Frame
los componentes que deseamos tan solo con arrastrar el componente desde la paleta
hasta el Frame y modificar sus propiedades.Para crear un Frame podemos seleccionar del
Proyecto new JFrame en lugar de Java Class. De esta manera se crear una clase con
algunos atributos ypropiedades de JFrame, incluyendo el mtodo main que permitir
visualizar elFrame al ejecutar la clase. VENTANAS DEL GENERADOR DE INTERFAZ
GRFICA
Al agregar un contenedor de JFrame a un proyecto el programa abre el formularioen una
ficha del Editor con una barra de herramientas que incluye varios botones. El formulario
se abre en la vista Diseo del generador de interfaces grficas deusuario y aparecen
automticamente tres ventanas adicionales en las esquinas delprograma, que permiten
navegar, organizar y editar los formularios de la interfaz grfica de usuario a medida que
los genera. Las diferentes ventanas del generador de interfaces grficas de usuario
incluyen:
rea de diseo: Ventana principal del generador de interfaces grficas de usuario para
crear y editar formularios de interfaz grfica de usuario de Java. Los botones Origen y
Diseo de la barra de herramientas permiten ver el cdigo fuente de una clase o la vista
grfica de sus componentes de la interfaz grfica de usuario. Los botones adicionales de
la barra de herramientas permiten acceder cmodamente a los comandos habituales, por
ejemplo para elegir entre los modos de seleccin o conexin, alinear componentes, definir
el comportamiento de cambio automtico del tamao de los componentes o pre visualizar
los formularios. Inspector: Proporciona una representacin, tanto visual como no visual,
de todos los componentes de la aplicacin en forma de jerarqua de rbol. El inspector
tambin permite visualizar el componente del rbol que se est editando en el generador
de interfaces grficas de usuario, as como organizar los componentes en los paneles
disponibles.
Paleta: Lista personalizable de los componentes disponibles que contiene fichas para los
componentes de JavaBeans, JFC/Swing y AWT, as como administradores de diseo.
Ventana de propiedades: Muestra las propiedades del componente seleccionado en el
generador de interfaces grficas de usuario y las ventanas Inspector, Proyectos o
Archivos.Mtodo initComponents()El cdigo del mtodo initComponents() es generado al
momento que se aadencomponentes al frame, es decir las propiedades y eventos que se
agreguen a loscomponentes, de manera que no se pueden editar desde aqu. La nica
manera de modificar o aumentar cdigo a ste mtodo es mediante lapestaa Code del
panel Properties en la vista diseo: Crear el componente Antes de crear el componente
Despus de crear el componente Para inicializar el valor del componente Despus de
inicializar el componente ..........
PRCTICA 1.
Crear un proyecto denominado ProyectoSwing. 2. Crear una clase PrimerFrame en un
paquete denominado presentacion. 3. Agregar los siguientes componentes y modificar
sus propiedades de diseo:Diseo: Asignamos nombres a cada componente:
129

Modificar el layout del panel Operaciones a BoxLayout El cuadro de texto de Resultado


no debe ser editable. Agregamos los eventos a cada botn de las operaciones:
Una vez seleccionado el evento estaremos en la vista Source en donde est todo el
cdigo generado al agregar y modificar los componentes. Modificamos el contenido del
mtodo actionPerformed de cada botn: El resultado ser el siguiente: Codificar los
eventos de cada botn y controlar las excepciones para el ingreso de texto en los campos
de nmero.EJERCICIO:Leer un archivo de texto desde un programa en java que permita
leer y modificar elcontenido en un JTextArea.Utilice el patrn Modelo Vista Controlador
para manejar los archivos
Uso de JFileChooser para buscar y abrir el archivo. Uso de JFileColor para cambiar el
color de fondo del rea de texto y el color de fuente. Uso del paquete java.io para la
lectura y escritura del Archivo.EJERCICIO:Elabore un programa que permita administrar en
una tabla (JTable) los datos de losestudiantes. Utilizar el patrn MVC, de manera que la
tabla pueda almacenar los estudiantes como objetos. Trabajar los eventos que
permiten actualizar los datos de la tabla al agregar, modificar o eliminar Utilizar la
opcin binding de Netbeans para obtener los datos del Estudiante.
BIBLIOGRAFA 1. PREZ Gustavo Guillermo, Aprendiendo Java y Programacin Orientada a
Objetos. http://compunauta.com/forums/linux/programacion/java/ebook.html 2. DEITEL
Paul. Como programar en Java 7/e. Pearson Education. 2007. 3. Micael Gallego & Soto
Montalvo,
Interfaces
Grficas
en
Java.
Ramn
Areces,
2005.
http://gavab.escet.urjc.es/wiki/download/mp/material/Modulo- Ev-Tema2-1.pdf 4. PAVN
GMEZ Santiago Dpto. Ingeniera Sistemas Telemticos Univ. Politcnica de Madrid
http://jungla.dit.upm.es/~santiago/docencia/apuntes/Swing/ 5. El tutorial Java de Sun:
http://java.sun.com/docs/books/tutorial
6.
Tutorial
Java
Bsico
Versin
3.0
http://www.javahispano.org
7.
API
Java
de
Sun
(version
6):
http://java.sun.com/javase/6/docs/apiProgramacion 2 Jhomara Luzuriaga
___________________________________Transformaciones de imgenes = http://www.lcc.uma.es/~galvez/ftp/libros/Java2D.pdf
http://www.alammi.info/2congreso/memorias/Documentos/martes/TRANSFORMGEOMETRI
CAS.pdf
Crop
You can crop or subset an image by providing an x,y offset from the upper left corner of
the image and a width/height.
javaxt.io.Image image = new javaxt.io.Image("/cup.jpg");
image.crop(130,50,80,50);
Original Image

130

Image Crop

Skew
You can adjust the corners of the image to arbitrary pixel coordinates. This can be used to
add perspective to your images.
javaxt.io.Image image = new javaxt.io.Image("/cup.jpg");
int width = image.getWidth();
int height = image.getHeight();
image.setCorners(20, 70,
//UL
width-70, 0,
//UR
width+20, height-50, //LR
50, height);
//LL
Original Image
Skewed Image
Accessing Raw Bytes
Note that you can access the raw pixels via the getByteArray() method.
byte[] b = image.getByteArray();
By default, this returns a jpeg compressed image. You can specify an output format
byte[] b = image.getByteArray("tif");
You can access the raw pixels via the getBufferedImage() method.
java.awt.image.BufferedImage bi = image.getBufferedImage();

________________________________

http://www.escet.urjc.es/~gperez/Interfaces/practicas/practica0.pdf
131

CLASES Y JERARQUIA DE PANELES Y COMPONENTES


Practica0 de Swing
1. Programa Java tipo consola
public class Clase0 {
public static void main(String[] args) {
System.out.println("Hola Mundo");
System.out.println("Estamos en clas
e de Interfaces de Usuario");
}
}
2. Programa grafico Java
2.1 Elementos grficos en Java.
Cada uno de los elementos de un interfaz grfic o de usuario en Java se representa por
una instancia de una determinada clase. Por ejemplo, si queremos que nuestro interfaz
tenga un botn, tendremos que, entre otras cosas, instanciar un objeto de la clase JButton
. Para configurar los aspectos grficos de los componentes usaremos mtodos en la clase
determinada. Por ejemplo, podremos cambiar el texto del botn usando el mtodo void
setText(String texto) de la clase JButton
.
En el siguiente cuadro se muestran los distintos tipos de elementos que se pueden
encontrar en Swing y el nombre de la clase que los representa:
Componentes atmicos
JLabel Etiqueta, muestra imgenes y texto. El texto se puede formatear con etiquetas
HTML.
JButton Botn
JCheckBox Casilla de verificacin
JRadioButton Botn de radio, usado para seleccionar una opcin entre varias
JToggleButton Botn que se queda presionado al pulsarle
JComboBox Control que muestra un elemento y pulsando en una flecha se pueden ver
otros elementos
JScrollBar Barra de desplazamiento, usada en los contenedores que permiten que su
contenido sea ms grande que ellos. Nunca usaremos este componente directamente.
JSeparator Usado en los menus y barras de herramientas para separar opciones.
JSlider - Deslizador
JSpinner Campo de texto con botones para elegir el elemento siguiente o anterior. Se
puede usar para nmeros, fechas o elementos propios.
JProgressBar Barra de progreso
Componentes complejos
JTable Tabla
JTree - rbol
JList Lista de elementos
JFileChooser Selector de ficheros
JColorChooser Selector de color
JOptionPane Cuadro de dilogo personalizable Ingeniera Informtica Swing
Componentes de texto
JTextField Campo de texto
JFormattedTextField Campo de texto formateado
132

JPasswordField Campo de texto para contraseas


JTextArea Area de texto
JTextPane Area de texto formateado y con imgenes
JEditorPane Area de texto formateado y con imgenes que permite la edicin del
contenido
Contenedores JPanel Contenedor
JScrollPane Contenedor con barras de desplazamiento
JSplitPane Contenedor dividido en dos partes
JTabbedPane Contenedor con pestaas
JDesktopPane Contenedor para incluir ventanas dentro
JToolBar Barra de herramientas
Contenedores de alto nivel
JFrame Ventana de aplicacin
JDialog Cuadro de dilogo
JWindow Ventana sin marco
JInternalFrame Ventana interna
Menus
JMenu Un botn que al ser pulsado despliega un men.
JCheckBoxMenuItem Elemento del men como botn de chequeo.
JRadioButtonMenuItem Elemento del men como botn de seleccin.
JPopupMenu Men de elementos.
JMenuItem Un botn que se encuentra en un menu.
JMenuBar Barra de menus.
Otros
JToolBar Barra de herramientas
JToolTip Tooltip
No vamos a ver todos los componentes en detalle. Este tutorialpretende mostrar los
conceptos bsicos de Swing y cmo construir interfaces potentes, pero no entra en los
detalles de cada componente. Se pretende que el lectortenga la capacidad de mirar la API
y comprender lo que se dice en ella sin dificultad. No obstante, a medida que vayamos
avanzando, iremos dando unas nociones bsicas en el uso de algunos componentes.
Debido a la evolucin que han sufrido los interfaces grficos de usuario en Java, en
algunos aspectos la librera de Swing es algo confusa.
Conceptualmente , podramos pensar que todos los componentes heredan de la clase
JComponent, todos aquellos que son contenedores, heredaran de JContainer , etc...
Una visin conceptual de la jerarqua de clases podra ser:
JComponent
AbstractButton
JButton
JMenuItem
JMenu
JCheckBoxMenuItem
JRadioButtonMenuItem
JToggleButton
JCheckBox
JRadioButton
133

JScrollBar
JSeparator
JPopupMenu.Separator
JToolBar.Separator
JSlider
JSpinner
JLabel
JList
JComboBox
JProgressBar
JToolTip
JTable
JTree
JTextComponent
JEditorPane
JTextPane
JTextArea
JTextField
JFormattedTextField
JPasswordField
JContainer
JToolBar
JPanel
JMenuBar
JPopupMenu
JTabbedPane
JScrollPane
JSplitPane
JLayeredPane
JDesktopPane
JTopLevelContainer
JInternalFrame
JFrame
JWindow
JDialog
JColorChooser
JFileChooser
JOptionPane
Pero, como hemos comentado antes, debido a motivos de compatibilidad, la verdadera
jerarqua es algo ms confusa, aunque conceptualmente seran muy parecidas. La
jerarqua de clases real que representa los elementos ms importantes del interfaz de
usuario es la siguiente:
class java.awt.Component
class java.awt.Container
class javax.swing.JComponent
class javax.swing.AbstractButton
134

class javax.swing.JButton
class javax.swing.JMenuItem
class javax.swing.JCheckBoxMenuItem
class javax.swing.JMenu
class javax.swing.JRadioButtonMenuItem
class javax.swing.JToggleButton
class javax.swing.JCheckBox
class javax.swing.JRadioButton
class javax.swing.JScrollBar
class javax.swing.JSeparator
class javax.swing.JPopupMenu.Separator
class javax.swing.JToolBar.Separator
class javax.swing.JSlider
class javax.swing.JSpinner
class javax.swing.JLabel
class javax.swing.JList
class javax.swing.JComboBox
class javax.swing.JProgressBar
class javax.swing.JColorChooser
class javax.swing.JFileChooser
class javax.swing.JOptionPane
class javax.swing.JPopupMenu
class javax.swing.JMenuBar
class javax.swing.JToolBar
class javax.swing.JToolTip
class
class
class
class

javax.swing.JTabbedPane
javax.swing.JScrollPane
javax.swing.JSplitPane
javax.swing.JLayeredPane
class javax.swing.JDesktopPane
class javax.swing.JPanel
class javax.swing.JTable
class javax.swing.JTree
class javax.swing.text.JTextComponent
class javax.swing.JEditorPane
class javax.swing.JTextPane
class javax.swing.JTextArea
class javax.swing.JTextField
class javax.swing.JFormattedTextField
class javax.swing.JPasswordField
class javax.swing.JInternalFrame
class java.awt.Panel
class java.awt.Window
135

class java.awt.Dialog
class javax.swing.JDialog
class java.awt.Frame
class javax.swing.JFrame
class javax.swing.JWindow
Ejemplo de un componente JFRAME
Java.lang.Object

Java.awt.Component

Java.awt.Container

Java.awt.Window

JFRAME
Es el contenedor que emplearemos para
situar en l todos los dems componentes
que sean necesarios para construir una
determinada interfaz.
La figura 1 muestra la jerarqua de herencia
de este componente desde Object, que es
el objeto padre de todas las clases de Java.
Sus mtodos estn repartidos a lo largo de
todos sus ascendientes. Vamos a ilustrar
esto con un ejemplo para ver el cdigo
necesario para crear un JFrame

Java.awt.Fra
me

Javax.
swing.JFrame
Figura 1. Jerarqua de la herencia de JFrame
2.1.1 Pasos bsicos para la creacin de un entorno grfico Una vez que hemos visto el
conjunto de componentes que Swing nos proporciona, vamos a ver como se construye un
interfaz de usuario sencillo. Vamos a mostrar como construir los elementos grficos y
dejamos para el siguiente apartado la gestin de eventos.
El interfaz grfico a construir estar formado por una ventana, y dentro de sta van a
aparecer un botn, una etiqueta y un cuadro de texto. Los pasos a seguir son los
siguientes:
Crear una ventana de aplicacin.
-Crear los componentes que se muestran en dicha ventana.
-Crear un contenedor.
-Asociar los componentes al contenedor para que, al hacerse visible, muestre en su
interior dichos componentes.
-Asociar el contenedor a la ventana de aplicacin para que, al hacerse visible, muestre en
su interior el contenedor y por tanto, los componentes asociados.
La jerarqua de contenedores de nuestro sencillo interfaz grfico sera:
Ventana de Aplicacin
Contenedor
136

Botn

Etiqueta

Campo de texto

NOTA: Cuando en un grfico vayamos a indicar que un componente se va a pintar dentro


de un determinado contenedor, usaremos una lnea terminada en un crculo del
contenedor al componente.
Crear la ventana de aplicacin Para crear una ventana de aplicacin hay que instanciar un
objeto de la clase JFrame
.
Algunos mtodos de esta clase relacionados con el aspecto grfico de la ventana son:
public JFrame()
Construye una ventana inicialmente invisible.
public JFrame(String titulo)
Construye una ventana inicialmente invisible con el ttulo indicado.
public void setTitle(String titulo)
Establece el ttulo de la ventana.
public void setSize(int width, int height)
Establece el tamao en pxeles de la ventana.
public void setDefaultCloseOperation(int operation)
Establece la operacin que se ha de hacer cuando el usuario cierra la ventana. Los
valores permitidos vienen determinados por las siguientes constantes:
Javax.swing.JFrame.EXIT_ON_CLOSE
- Salir del programa.
Javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE
- No hacer nada.
Javax.swing.WindowConstants.HIDE_ON_CLOSE
- Ocultar la ventana (por defecto).
Javax.swing.WindowConstants.DISPOSE_ON_CLOSE
Liberar los recursos de la ventana, pero no salir del programa.
public void setResizable(boolean resizable)
Establece si el usuario puede cambiar el tamao de la ventana. Por defecto es true.
public void setExtendedState(int state)
Establece el estado de la ventana. Puede no funcionar en algunas plataforms. Los
valores permitidos vienen dados por las constantes:
Java.awt.Frame.NORMAL
No se encuentra ni minimizada ni maximizada.
Java.awt.Frame.ICONIFIED
Minimizada.
Java.awt.Frame.MAXIMIZED_BOTH
137

- Maximizada.
Java.awt.Frame.MAXIMIZED_HORIZ
Maximizada horizontalmente.
Java.awt.Frame.MAXIMIZED_VERT
Maximizada verticalmente.
public void setLocation(int x, int y)
Establece la posicin de la esquina superior izquierda de la ventana.
public void setVisible(boolean visible)
Muestra u oculta la ventana.
Crear los componentes
Para crear un componente, basta crear una instancia de la clase determinada y configurar
ese objeto para que se adapte a nuestras necesidades. Vamos a ver algunos mtodos de
los aspectos grficos de algunos de los componentes ms usados:
JButton
public JButton(String texto)
- Crea un botn con el texto indicado.
JLabel
public JLabel(String texto)
- Crea una etiqueta con el texto indicado.
public String getText()
- Devuelve el texto de la etiqueta.
public void setText(String texto)
- Pone el texto indicado en la etiqueta.
JTextField
public JTextField(int columnas)
- Crea un Campo de Texto sencillo con el nmero de columnas especificado.
public String getText()
- Devuelve el texto del campo de texto.
A medida que vayamos avanzando en el curso iremos viendo los componentes ms
importantes y los mtodos que permiten configurar su aspecto grfico.
Crear un contenedor
Como hemos visto, en Swing existen muchos tipos de contenedores, dependiendo de la
forma que manejen los componentes que tienen dentro. Por ejemplo, existe un
contenedor con pestaas y en cada pestaa va un componente, es el JTabbedPane
.
Tambin existe otro contenedor dividido en dos partes para dos componentes, y la
separacin puede cambiar de posicin, es el JSplitPane

138

. El que nosotros vamos a usar, para construir nuestro sencillo interfaz, es el JPanel , el
ms sencillo de todos, que muestra todos los componentes a la vez distribuidos en su
interior. Ms adelante veremos como podemos configurar la forma de distribuir los
componentes.
El mtodo constructor de la clase JPanel es:
public JPanel()
Crea un contenedor simple
Asociar los componentes al contenedor para que los muestre al hacerse visible
Para asociar componentes a un contenedor, de forma que se muestren dentro cuando el
contenedor se muestre por pantalla, usamos el siguiente mtodo de la clase JPanel
:
public void add( JComponent componente )
Asocia el componente al contenedor, de forma que se muestre el componente al
mostrarse el contenedor.
NOTA: Por motivos de compatibilidad la cabecera real del mtodo es public void
add(Component comp). Puesto que vamos a trabajar con Swing podemos considerar que
la cabecera es la indicada.
Asociar el contenedor a la ventana para que le muestre al hacerse visible
Para asociar un contenedor a la ventana de aplicacin, de forma que se muestre dentro
cuando la ventana se muestre por pantalla, usaremos el siguiente mtodo de la clase
JFrame
:
public void setContentPane(JComponent panelDeContenido)
Establece el componente pasado como parmetro como contenido de la ventana.
NOTA: Por motivos de compatibilidad la cabecera real del mtodo es public void
setContentPane(Container contentPane). Puesto que vamos a trabajar con Swing podemos
considerar que la cabecera es la indicada.
Ejemplo de cdigo de una interfaz grafico
//
importamos la libreria, un package
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
//
La clase frame extiende a JFrame
class frame extends JFrame {
//
el constructor
public frame(){
//Este es uno de los mtodos que nuestra clase frame
//ha heredado de JFrame. Pone un titulo a la ventana
setTitle("Hola!!!");
//
Igual que el anterior, pero ahora le da un tamao
setSize(300,200);
//
Le pido al frame su objeto contenedor
Container contentpane = getContentPane();
139

//
Creo un objeto de tipo JPanel
JPanel panel = new JPanel();
//
Creo un objeto tipo label
JLabel hola = new JLabel("Hola Mundo");
JLabel hola1= new JLabel("Estamos en clase de Interfaces de Usuario");
//
aado el panel en el objeto contenedor del frame
contentpane.add(panel);
//
Pongo el color de fondo del panel de color rojo
//
aado los labels en el objeto contenedor del frame
contentpane.add(hola);
contentpane.add(hola1);
}
}
//
Esta es la clase auxiliar y tiene el main de la aplicacin
public class ejem1{
public static void main (String[] args){
//creamos un objeto de tipo frame
JFrame frame = new frame();
//
Hacemos que los objetos se distribuyan automaticamente en el contenedor
frame.getContentPane().setLayout(new FlowLayout());
//Invoco sobre este objeto uno de los mtodos que
//ha heredado de frame. Hacer visible el frame. Los frame por
//defecto son invisibles.
//Tambien se puede con show
.
frame.setVisible(true);
}
}
Ejercicio 1
Ya hemos visto los mtodos y clases para la creacin de un sencillo interfaz de usuario,
partiendo de esta informacin, crea la interfaz grafico teniendo en cuenta los
componentes que se muestran en la Figura 2.
http://dis.um.es/~bmoros/Tutorial/parte14/cap14-17.html para estudiar maana
Paneles Desplazables
Anterior | Siguiente
En anteriores programas se ha utilizado la clase JScrollPane para proporcionar una forma
automtica de desplazar el contenido de una ventana por parte del sistema. Esta clase
permite dejar las manos libres al programador para centrarse en el cdigo de su
140

aplicacin, sin tener que estar pendiente de tener que controlar la visibilidad de todo o
parte del contenido de la ventana. Pero los ejemplos que se han visto no se centraban
ninguno en la clase JScrollPane, por lo que son muy simples, pero visto que es una clase
muy usada y til, el ejemplo java1424.java es para presentar una aplicacin un poco ms
avanzada para mostrar cmo interacta en un programa. Adems, el ejemplo hace uso de
la clase JSplitPane, que permite dividir la ventana en subventanas independientes.
El programa implementa un JFrame que contiene un panel dividido en dos zonas, cada
una conteniendo una instancia de un componente Swing. La zona superior de la ventana
contiene un campo de texto y la inferior un grfico, para ilustrar el hecho de que el
contenido de los paneles de desplazamiento puede ser cualquiera que se elija.
El cdigo del ejemplo se muestra a continuacin y debera resultar sencillo de entender al
lector, aunque hay algunos trozos sobre los que merece la pena detenerse y se
comentarn a continuacin.
import
import
import
import
import

java.io.*;
java.awt.*;
java.awt.event.*;
com.sun.java.swing.*;
com.sun.java.swing.event.*;

class java1424 extends JPanel implements ChangeListener {


private JSplitPane panelVert;
private JScrollPane panelScro1;
private JScrollPane panelScro2;
public java1424() {
setLayout( new BorderLayout() );
// Se crea una zona para presentar el texto correspondiente al fichero
creaPanelSup();
// Se crea una zona inferior para mostrar el grfico
creaPanelInf();
// Se crea un panel dividido verticalmente
panelVert = new JSplitPane( JSplitPane.VERTICAL_SPLIT );
add( panelVert,BorderLayout.CENTER );
// Se incorporan las dos zonas que se haban creado a las dos
// partes en que se ha dividido el panel principal
panelVert.setLeftComponent( panelScro1 );
panelVert.setRightComponent( panelScro2 );
}
public void stateChanged( ChangeEvent evt ) {
// Si el evento proviene del panel principal, seguimos...
if( evt.getSource() == panelScro1.getViewport() ) {
// Cogemos la posicin actual dentro de la vista correspondiente
// al panel principal
Point point = panelScro1.getViewport().getViewPosition();
// Ahora determinamos la escala correcta para las vistas, para las
// dos zonas del panel principal
Dimension dim1 = panelScro1.getViewport().getViewSize();
141

Dimension dim2 = panelScro2.getViewport().getViewSize();


float escalaX = 1;
float escalaY = 1;
if( dim1.width > dim2.width ) {
escalaX = (float)dim1.width / (float)dim2.width;
escalaY = (float)dim1.height / (float)dim2.height;
// Escalamos en funcin del movimiento
point.x /= escalaX;
point.y /= escalaY;
}
else {
escalaX = (float)dim2.width / (float)dim1.width;
escalaY = (float)dim2.height / (float)dim1.height;
// Escalamos en funcin del movimiento
point.x *= escalaX;
point.y *= escalaY;
}
// Movemos la otra vista en funcin de lo que movamos la de texto
panelScro2.getViewport().setViewPosition( point );
}
}
private void creaPanelSup() {
// Creamos el panel de la zona de texto
JTextArea areaTexto = new JTextArea();
// Se carga el fichero en el rea de texto, cuidando de capturar
// todas las excepciones que se puedan producir
try {
FileReader fileStream = new FileReader( "java1424.java" );
areaTexto.read( fileStream, "java1424.java" );
} catch( FileNotFoundException e ) {
System.out.println( "Fichero no encontrado" );
} catch( IOException e ) {
System.out.println( "Error por IOException" );
}
// Creamos el panel desplazable para el rea de texto
panelScro1 = new JScrollPane();
panelScro1.getViewport().add( areaTexto );
panelScro1.getViewport().addChangeListener( this );
}
private void creaPanelInf() {
// Cargamos el grfico, o imagen , en la panatalla
Icon imagenP2 = new ImageIcon( "main.gif" );
JLabel etiqP2 = new JLabel( imagenP2 );
// Creamos el panel para el grfico
panelScro2 = new JScrollPane();
panelScro2.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
142

panelScro2.setHorizontalScrollBarPolicy(
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
panelScro2.getViewport().add( etiqP2 );
panelScro2.getViewport().addChangeListener( this );
}
public static void main( String args[] ) {
JFrame ventana = new JFrame( "Tutorial de Java, Swing" );
ventana.addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent evt ){
System.exit( 0 );
}
} );
ventana.getContentPane().add( new java1424(),BorderLayout.CENTER );
ventana.setSize( 460,300 );
ventana.setVisible( true );
}
}
Los mtodos que se usan para crear el contenido de los subpaneles es complicado. El
mtodo creaPanelSup(), se limita a utilizar un componente JTextArea sobre el que carga el
fichero que contiene el cdigo fuente del ejemplo. y el mtodo creaPanelInf() presenta
una imagen que se desplazar en consonancia con el movimiento del panel superior.
Sin embargo, s que hay un trozo de cdigo interesante en el mtodo stateChanged(), que
controla los cambios producidos por accin del usuario, y es el clculo de la escala que
diferencia a los dos paneles de desplazamiento. En el programa, el clculo de la escala no
es demasiado preciso, debido a que no tiene en cuenta del todo el tamao de los dos
paneles. Si se mueve la barra horizontal en el panel superior se puede observar esta
circunstancia. Con un poco ms de matemticas por parte del lector, seguro que podr
compensar el error, y a su ejercicio se deja esa correccin, simplemente indicando que
hay que experimentar con los mtodos getViewPosition() y getExtentSize() de la clase
JViewport para conseguir que los clculos sean correctos.

143

Cuando se ejecuta el programa y se agranda la ventana, se puede ver una imagen


semejante a la que reproduce la imagen siguiente.
Ahora, los movimientos sobre la barra de desplazamiento vertical en el panel superior
hacen que la imagen que esta en el panel inferior se desplace al mismo tiempo. Quiza
esto no le parezca al lector demasiado prctico, pero muestra cmo se puede conseguir el
desplazamiento de un panel con respecto a otro; y este tipo de funcionalidad s que es de
uso frecuente en muchas aplicaciones, y aqu se muestra una forma muy sencilla de
poder implementarla.
Otro detalle importante es la ausencia de barras de desplazamiento en el panel inferior, a
pesar de que la imagen es mucho ms grande que el tamao de la subventana. Las lneas
de cdigo siguientes:
panelScro2.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER );
panelScro2.setHorizontalScrollBarPolicy(
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
son las que permiten fijar las caractersticas de las barras de desplazamiento, y en este
caso se indica que no deben estar presentes.
hola,
tengo este problema, quiero mostrar una imagen de 125x100 cmts con 40 pixeles por cmt
= 5000x4000 pixeles, cre un JScrollPane de 5020x4020 pixeles, le agrego el Jlabel, le
aado la imagen a la propiedad icon (directamente en el IDE), no me muestra la imagen,
peor, no la acepta en la propiedad.
He tratado con mtodo y cdigo escrito en la clase, pero tampoco la muestra.
Cul puede ser el problema???
si quieres te envo la imagen, est en jpg con solo 2,86MB.
Te agradezco tu ayuda.
http://docs.oracle.com/javase/7/docs/api/java/awt/geom/AffineTransform.html
El sistema de coordenadas que proporciona Java para dibujar no es el ms adecuado para
la representacin de funciones matemticas. En primer lugar no est orientado a la forma
convencional de trabajar de utilizar los ejes de coordenadas con el origen en el centro y
los cuatro cuadrantes. En segundo lugar los pxel no son las unidades ms convenientes
para trabajar. El paquete Java 2D ofrece un sistema para cambiar las coordenadas. Una
transformacin afn de un plano se puede definir de la forma:
$x' = ax + by + c$
$y'= dx + ey + f $
[ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
[ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
144

[1] [ 0

1 ][1] [

@ConstructorProperties(value={"scaleX","shearY","shearX","scaleY","translateX","translat
eY"})
public AffineTransform(float m00,
float m10,
float m01,
float m11,
float m02,
float m12)
Constructs a new AffineTransform from 6 floating point values representing the 6
specifiable entries of the 3x3 transformation matrix.
Parameters:
m00 - the X coordinate scaling element of the 3x3 matrix
m10 - the Y coordinate shearing element of the 3x3 matrix
m01 - the X coordinate shearing element of the 3x3 matrix
m11 - the Y coordinate scaling element of the 3x3 matrix
m02 - the X coordinate translation element of the 3x3 matrix
m12 - the Y coordinate translation element of the 3x3 matrix
public static AffineTransform getTranslateInstance(double tx,
double ty)
Returns a transform representing a translation transformation. The matrix representing
the returned transform is:
[ 1 0 tx ]
[ 0 1 ty ]
[ 0 0 1 ]
Parameters:
tx - the distance by which coordinates are translated in the X axis direction
ty - the distance by which coordinates are translated in the Y axis direction
Returns:
an AffineTransform object that represents a translation transformation, created with the
specified vector.
public static AffineTransform getScaleInstance(double sx,
double sy)
Returns a transform representing a scaling transformation. The matrix representing the
returned transform is:
[ sx 0 0 ]
[ 0 sy 0 ]
[ 0 0 1 ]
Parameters:
sx - the factor by which coordinates are scaled along the X axis direction
sy - the factor by which coordinates are scaled along the Y axis direction
Returns:
an AffineTransform object that scales coordinates by the specified factors.
public static AffineTransform getShearInstance(double shx,
double shy)
145

Returns a transform representing a shearing transformation. The matrix representing the


returned transform is:
[ 1 shx 0 ]
[ shy 1 0 ]
[ 0 0 1 ]
Parameters:
shx - the multiplier by which coordinates are shifted in the direction of the positive X axis
as a factor of their Y coordinate
shy - the multiplier by which coordinates are shifted in the direction of the positive Y axis
as a factor of their X coordinate
Returns:
an AffineTransform object that shears coordinates by the specified multipliers.
Since:
Las transformaciones de este tipo tienen la propiedad de que las lneas se transforman en
lneas y los conjuntos de lneas paralelas se transforman en conjuntos de lneas paralelas.
Para crear una transformacin de este tipo usamos el constructor:
AffineTransform t = new AffineTransform(a, b, c, d, e, f);
void setTransform(double m00, double m10, double m01, double m11, double m02,
double m12)
Sets this transform to the matrix specified by the 6 double precision values.
public static final int TYPE_GENERAL_TRANSFORM
This constant indicates that the transform defined by this object performs an arbitrary
conversion of the input coordinates. If this transform can be classified by any of the above
constants, the type will either be the constant TYPE_IDENTITY or a combination of the
appropriate flag bits for the various coordinate conversions that this transform performs.
Por ejemplo, el mtodo paintComponent puede aplicar una transformacin que le permita
hacer que el origen est en el centro del panel de visualizacin, para ello tiene que
establecer la transformacin de coordenadas a una traslacin:
g2.translate(getWidth()/2, getHeight()/2);
Existen cuatro tipos de transformaciones fundamentales:
Distorsin: manteniendo una lnea fija, deslizar todas las lneas paralelas a ella una
distancia proporcional a la distancia que hay desde la lnea fija.
objetoGrfico.shear(double sx, double xy)
Constructores de la clase Shape3D:
Shape3D();
Construye e inicializa el objeto sin ningn tipo de referencia a un objeto componente.
Shape3D(Geometry g);

146

Construye e inicializa un objeto hoja con referencia al objeto de geometra g. La


referencia a un objeto de apariencia es nulo.
Constructor de GeometryArray:
GeometryArray(int cantidadVrtices, int formatoVrtices);
Construye un objeto vaco con el nmero de vrtices y el formato indicado. En el indicador
de formato se puede utilizar los constantes unidos por el operador OR. Los constantes
indicadores de formato son:
COORDINATES. Se utiliza un array de coordenadas. ste es obligatorio.
NORMALS. Array de superficies normales.
COLOR_3. Colores sin transparencia.
3.3.3 Dibujo de polgonos
3.3.3.1 Tringulos
El siguiente cdigo de ejemplo crea dos tringulos.
private Node CrearTringulo() {
TriangleArray tringulo = new TriangleArray(6, TriangleArray.COORDINATES|
TriangleArray.COLOR_3);
tringulo.setCoordinate(0, new Point3f(-0.8f, 0.5f, 0.0f));
tringulo.setCoordinate(1, new Point3f(-0.8f,-0.5f, 0.0f));
tringulo.setCoordinate(2, new Point3f( 0.0f,-0.5f, 0.0f));
tringulo.setCoordinate(3, new Point3f( 0.0f, 0.5f, 0.0f));
tringulo.setCoordinate(4, new Point3f( 0.8f,-0.5f, 0.0f));
tringulo.setCoordinate(5, new Point3f( 0.8f, 0.5f, 0.0f));

tringulo.setColor(0, new Color3f(1.0f, 0.0f, 0.0f)); // Rojo


tringulo.setColor(1, new Color3f(0.0f, 1.0f, 0.0f)); // Verde
tringulo.setColor(2, new Color3f(0.0f, 0.0f, 1.0f)); // Azul
tringulo.setColor(3, new Color3f(1.0f, 1.0f, 0.0f)); // Amarillo
tringulo.setColor(4, new Color3f(0.0f, 1.0f, 1.0f)); // Cin
tringulo.setColor(5, new Color3f(1.0f, 0.0f, 1.0f)); // Violeta

147

Shape3D forma = new Shape3D(tringulo);


return forma;
}
En la figura 3.7 se muestra el resultado. Se coge los vrtices de tres en tres para dibujar
los tringulos. El orden de los vrtices en el array es importante. Tiene que ponerse en
orden antihorario si se quiere que la cara visible sea la frontal.
Se puede crear polgonos ms complejos basados en tringulos. El siguiente ejemplo hace
esto.
private Node CrearTringulo() {
int contadorTira[] = {4, 5};
TriangleStripArray tringulo = new TriangleStripArray(9, TriangleArray.COORDINATES|
TriangleArray.COLOR_3, contadorTira);
// Primera tira
tringulo.setCoordinate(0, new Point3f(-0.8f, 0.5f, 0.0f));
tringulo.setCoordinate(1, new Point3f(-0.8f,-0.4f, 0.0f));
tringulo.setCoordinate(2, new Point3f(-0.2f, 0.5f, 0.0f));
tringulo.setCoordinate(3, new Point3f(-0.3f,-0.5f, 0.0f));
// Segunda tira
tringulo.setCoordinate(4, new Point3f( 0.1f, 0.5f, 0.0f));
tringulo.setCoordinate(5, new Point3f( 0.0f,-0.5f, 0.0f));
tringulo.setCoordinate(7, new Point3f( 0.3f,-0.5f, 0.0f));
tringulo.setCoordinate(6, new Point3f( 0.3f, 0.2f, 0.0f));
tringulo.setCoordinate(8, new Point3f( 0.8f, 0.0f, 0.0f));

Color3f rojo = new Color3f(1.0f, 0.0f, 0.0f); // Rojo


Color3f verde = new Color3f(0.0f, 1.0f, 0.0f); // verde
Color3f azul = new Color3f(0.0f, 0.0f, 1.0f); // azul

148

tringulo.setColor(0, rojo);
tringulo.setColor(1, verde);
tringulo.setColor(2, azul);
tringulo.setColor(3, rojo);
tringulo.setColor(4, verde);
tringulo.setColor(5, azul);
tringulo.setColor(6, rojo);
tringulo.setColor(7, verde);
tringulo.setColor(8, azul);

Shape3D forma = new Shape3D(tringulo);


return forma;
}
La figura 3.9 muestra el resultado. La clase TriangleStripArray es similar a la clase
LineStripArray. En el ejemplo se crea dos polgonos. El primero consta de 4 vrtices que
forma dos tringulos. El segundo tiene 5 vrtices formando 3 tringulos.
Para agrupar
dibujos formando una imagen = https://books.google.com.co/books?
id=M6reV4TGyIQC&pg=PA40&lpg=PA40&dq=coordenadas+float+or+double+en+java&s
ource=bl&ots=jeoUoh2tDP&sig=S_aYPLRzoN6scPvWztwFu1av0I&hl=es&sa=X&ei=U7uQVPr9HsSUNuKqguAO&ved=0CDEQ6AE
wAw#v=onepage&q=coordenadas%20float%20or%20double%20en%20java&f=false

149

También podría gustarte